2

lucene.net に基づく Examine 検索を使用している Umbraco Web サイトがあります。私は、次の記事で説明されていることを正確に実行しようとしています。

Examine と Lucene.Net を使用してコンマ区切りの ID リストに対してクエリを実行しますか?

私が抱えている問題は、次のコードを使用してインデックスを作成しようとしているときです。

// Loop through articles
        foreach (var a in articles)
        {
            yield return new SimpleDataSet()
            {
                NodeDefinition = new Examine.IndexedNode()
                {
                    NodeId = a.Id,
                    Type = "Article"

                },
                RowData = new Dictionary<string, string>()
                {
                    {"Name", a.Name},
                    {"Url", a.NiceUrl},
                    {"Category", "1234"},
                    {"Category", "5678"}
                }
            };
        }

次のエラーが表示されます。

同じキーを持つアイテムが既に追加されています。

この問題を回避する方法を知っている人はいますか?

4

4 に答える 4

1

Dictionary<TKey, TValue>表示されているエラーは、 @DavidH で言及されている.NET のクラスの制限です。この制限は Examine のSimpleDataSetクラスから継承されており、ソースDictionary<string, string>を参照することで、ドキュメントに行データを追加する方法としてのみ許可されます。

ただし、LuceneDocument では、リンクされた質問に記載されているように、同じ名前の複数のフィールドを追加できます。

using Lucene.Net.Documents;

var document = new Document();
document.Add(CreateField("Id", a.Id));
document.Add(CreateField("Name", a.Name));
document.Add(CreateField("Url", a.NiceUrl));        
document.Add(CreateField("Category", "1234"));    
document.Add(CreateField("Category", "5678"));    

...

private Field CreateField(string fieldName, string fieldValue)
{
    return new Field(
        fieldName, 
        fieldValue, 
        Field.Store.YES, 
        Field.Index.ANALYZED);
}

Examine の API ほど便利ではありませんが、ネイティブで Lucene を使用すると、これらのシナリオでははるかに柔軟になります。

于 2013-05-31T14:41:24.407 に答える
0

これは lucene でそれを行う完全な例ですが、前述のように、 Examine は Dictionary に入力することで柔軟性を制限しているようです。ただし、それを処理するように変更するのは簡単なはずです。

public static void Main (string[] args)
    {
        Analyzer analyser = new StandardAnalyzer (Lucene.Net.Util.Version.LUCENE_CURRENT);
        Directory dir = new RAMDirectory ();

        using (IndexWriter iw = new IndexWriter (dir, analyser, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED)) {

            Document doc1 = new Document ();
            doc1.Add (new Field("title", "multivalued", Field.Store.YES, Field.Index.ANALYZED));
            doc1.Add (new Field("multival", "val1", Field.Store.YES, Field.Index.ANALYZED));
            doc1.Add (new Field("multival", "val2", Field.Store.YES, Field.Index.ANALYZED));
            iw.AddDocument (doc1);
            Document doc2 = new Document ();
            doc2.Add (new Field("title", "singlevalued", Field.Store.YES, Field.Index.ANALYZED));
            doc2.Add (new Field("multival", "val1", Field.Store.YES, Field.Index.ANALYZED));        
            iw.AddDocument (doc2);
        }

        using (Searcher searcher = new IndexSearcher (dir, true)) {
            var q1 = new TermQuery (new Term ("multival", "val1"));
            var q1result = searcher.Search (q1, 1000);

            //Will print "Found 2 documents"
            Console.WriteLine ("Found {0} documents", q1result.TotalHits);

            var q2 = new TermQuery (new Term ("multival", "val2"));
            var q2result = searcher.Search (q2, 1000);
            //Will print "Found 1 documents"
            Console.WriteLine ("Found {0} documents", q2result.TotalHits);
        }
    }
于 2013-05-31T16:13:37.877 に答える
0

ディクショナリ キーは一意である必要があり、これは Lucene に固有のものではなく、.NETDictionary<TKey, TValue>クラスに固有のものです。考えられるオプションの 1 つは、1 つの "Category" 辞書キーの下で値をパイプで区切り、パイプ文字で分割してそれらを解析することです。

RowData = new Dictionary<string, string>()
{
    {"Name", a.Name},
    {"Url", a.NiceUrl},
    {"Category", "1234|5678"}
}

string.Split次に、パイプ文字「|」で使用できます それらを解析して戻します。

于 2013-05-29T15:34:37.757 に答える