lucene.net 3.0.3索引空间太慢

时间:2013-03-18 22:47:14

标签: c# lucene.net spatial lucene

我最近将搜索代码从lucene.net 2.9.4升级到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,我能够在大约11分钟内使用lat / lng点对大约300,000行数据进行索引。使用这个新的空间包需要花费超过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的新实例以在新文档中使用(在lucene.net 3.0.3中,TokenStream的构造函数受到保护)。我在空间策略中将maxLevels int降低到了4,但我没有看到索引时间有所改善。任何反馈将不胜感激。

1 个答案:

答案 0 :(得分:0)

更新:我将SpatialStrategy更改为PointVectorStrategy,现在我的索引时间缩短为11分钟,大约300,000个文档。关键是缓存由添加到Documents时使用的形状创建的IndexableFields。 PointVectorStrategy允许这样做,因为它为索引创建NumericFields。使用RecursiveTreePrefixStrategy是不可能的,因为它使用TokenStreams创建了用于索引的Fields。在Lucene.net 3.0.3中,TokenStreams不可重用于索引。感谢大家帮忙解决这个问题。