2

最近、検索コードをlucene.net2.9.4から3.0.3にアップグレードしました。空間パッケージの変更に気づき、それに応じてコードを更新しました。私が気付いたアップグレードの欠点の1つは、インデックス時間がはるかに遅いことです。除去のプロセスを通じて、緯度/経度座標にインデックスを付ける新しい空間コードに速度を絞り込むことができました。

        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のコンストラクターが保護されています) )。空間戦略でmaxLevelsintを4に下げましたが、インデックス作成時間の改善は見られませんでした。フィードバックをいただければ幸いです。

4

1 に答える 1

0

更新: SpatialStrategy を PointVectorStrategy に変更したところ、約 300,000 ドキュメントのインデックス作成時間が 11 分に短縮されました。これの鍵は、ドキュメントに追加するときに使用するシェイプによって作成された IndexableFields をキャッシュすることでした。PointVectorStrategy は、インデックス用の NumericFields を作成するため、これを可能にします。これは、RecursiveTreePrefixStrategy では不可能です。これは、インデックス作成のために TokenStreams を使用してフィールドを作成するためです。Lucene.net 3.0.3 では、TokenStreams はインデックス作成に再利用できません。これを手伝ってくれてありがとう。

于 2013-05-07T04:38:10.047 に答える