2013-03-18 57 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