2013-03-18 139 views
2

我最近將我的搜索代碼從lucene.net 2.9.4升級到3.0.3。我注意到空間包中的變化,並相應地更新了我的代碼。我注意到升級的一個缺點是索引時間要慢得多。通過排除法,我已經能夠縮小緩慢下降到新的空間代碼索引經/緯座標:lucene.net 3.0.3索引空間太慢

 public void AddLocation (double lat, double lng) 
    { 
     try 
     { 
      string latLongKey = lat.ToString() + "," + lng.ToString(); 
      AbstractField[] shapeFields = null; 
      Shape shape = null; 
      if (HasSpatialShapes(latLongKey)) 
      { 
       shape = SpatialShapes[latLongKey]; 
      } 
      else 
      { 
       if (this.Strategy is BBoxStrategy) 
       { 
        shape = Context.MakeRectangle(DistanceUtils.NormLonDEG(lng), DistanceUtils.NormLonDEG(lng), DistanceUtils.NormLatDEG(lat), DistanceUtils.NormLatDEG(lat)); 
       } 
       else 
       { 
        shape = Context.MakePoint(DistanceUtils.NormLonDEG(lng), DistanceUtils.NormLatDEG(lat)); 
       } 

       AddSpatialShapes(latLongKey, shape); 
      } 

      shapeFields = Strategy.CreateIndexableFields(shape); 
      //Potentially more than one shape in this field is supported by some 
      // strategies; see the javadocs of the SpatialStrategy impl to see. 
      foreach (AbstractField f in shapeFields) 
      { 
       _document.Add(f); 
      } 
      //add lat long values to index too 
      _document.Add(GetField("latitude", NumericUtils.DoubleToPrefixCoded(lat), Field.Index.NOT_ANALYZED, Field.Store.YES, 0f, false)); 
      _document.Add(GetField("longitude", NumericUtils.DoubleToPrefixCoded(lng), Field.Index.NOT_ANALYZED, Field.Store.YES, 0f, false)); 
     } 
     catch (Exception e) 
     { 
      RollingFileLogger.Instance.LogException(ServiceConstants.SERVICE_INDEXER_CONST, "Document",string.Format("AddLocation({0},{1})", lat.ToString(), lng.ToString()), e, null); 
      throw e; 
     } 
    } 

隨着2.9.4,我能夠與指數約300,000行數據經過大約11分鐘的lat/lng分。有了這個新的空間包,它需要5個小時以上的時間(我在測試結束之前殺掉了測試,所以我沒有確切的時間安排)。這裏是空間環境/戰略我使用:

public static SpatialContext SpatialContext 
    { 
     get 
     { 
      if (null == _spatialContext) 
      { 
       lock (_lockObject) 
       { 
        if(null==_spatialContext) _spatialContext = SpatialContext.GEO; 
       } 
      } 
      return _spatialContext; 
     } 
    } 

    public static SpatialStrategy SpatialStrategy 
    { 
     get 
     { 
      if (null == _spatialStrategy) 
      { 
       lock (_lockObject) 
       { 
        if (null == _spatialStrategy) 
        { 
         int maxLength = 9; 
         GeohashPrefixTree geohashPrefixTree = new GeohashPrefixTree(SpatialContext, maxLength); 
         _spatialStrategy = new RecursivePrefixTreeStrategy(geohashPrefixTree, "geoField");       
        } 
       } 
      } 
      return _spatialStrategy; 
     } 
    } 

有什麼我與我的索引方法做錯了什麼?我已經緩存了由lat/lng點創建的形狀,因爲我不需要相同座標的新形狀。它似乎是在索引期間花費最多時間的CreateIndexableFields()方法。我試圖緩存這個方法生成的字段重用,但我無法從緩存的字段中創建一個新的TokenStream實例用於新的Document(在lucene.net 3.0.3中,TokenStream的構造函數受保護)。我在空間策略中將maxLevel int降至4,但我沒有看到索引時間的改進。任何反饋將不勝感激。

+0

你爲什麼不直接問Lucene.Net社區'用戶AT lucenenet.apache.org'(http://lucenenet.apache.org/) – I4V 2013-03-18 23:00:06

+0

謝謝,我確實看過那個社區,不幸的是有沒有太多的信息在最新的空間包的方式。我希望一些spatial4j開發者可能會看看這個。 – 2013-03-18 23:14:23

+0

你調試過嗎? Lucene使用控制流的異常,並減慢索引或搜索......我所做的,儘可能地避免它們(即傳遞參數以這種方式異常不會像沒有空目錄一樣拋出,所以lucene必須拋出異常創建目錄的文件夾)。我實際上改變了控制流程,不使用異常...高級,但它改進了我的應用程序的性能10x – 2013-03-22 22:33:43

回答

0

UPDATE:我將SpatialStrategy更改爲PointVectorStrategy,現在我的索引時間可以縮短到11分鐘,可處理約300,000個文檔。關鍵是緩存由添加到文檔時使用的形狀創建的IndexableField。 PointVectorStrategy允許這樣做,因爲它爲索引創建了NumericFields。這對於RecursiveTreePrefixStrategy來說是不可能的,因爲它使用TokenStreams創建帶索引的字段。在Lucene.net 3.0.3中,TokenStreams不適用於索引。感謝大家爲此提供幫助。

+0

您好,我正在嘗試使用Lucene 3.0.3存儲經緯度,然後對它們進行搜索。我對Lucene非常陌生。我沒有找到任何使用新版本的代碼示例。你可以請一些指導/代碼示例幫忙嗎?謝謝 – 2015-05-28 13:04:15