3

ドキュメントにフィールドを追加するときに SetBoost メソッドをテストするために、次のコードを作成しました。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Lucene;
using Lucene.Net;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using Lucene.Net.Store;
using Directory = Lucene.Net.Store.Directory;
using Version = Lucene.Net.Util.Version;

namespace LuceneTest
{
    public class LuceneTest
    {
        static void Main(string[] args)
        {
            var product1 = new Document();
            product1.Add(new Field("Id", "1", Field.Store.YES, Field.Index.NOT_ANALYZED));
            var title1 = new Field("title", "Special One", Field.Store.YES, Field.Index.ANALYZED);
            title1.SetBoost(2f);
            product1.Add(title1);
            product1.Add(new Field("synopsis", "special synopsis", Field.Store.YES, Field.Index.ANALYZED));

            var product2 = new Document();
            product2.Add(new Field("Id", "2", Field.Store.YES, Field.Index.NOT_ANALYZED));
            var title2 = new Field("title", "Special Two", Field.Store.YES, Field.Index.ANALYZED);
            title2.SetBoost(2f);
            product2.Add(title2);
            product2.Add(new Field("synopsis", "special synopsis", Field.Store.YES, Field.Index.ANALYZED));

            var product3 = new Document();
            product3.Add(new Field("Id", "3", Field.Store.YES, Field.Index.NOT_ANALYZED));
            var title3 = new Field("title", "Normal One", Field.Store.YES, Field.Index.ANALYZED);
            title3.SetBoost(2f);
            product3.Add(title3);
            product3.Add(new Field("synopsis", "special synopsis", Field.Store.YES, Field.Index.ANALYZED));

            var product4 = new Document();
            product4.Add(new Field("Id", "4", Field.Store.YES, Field.Index.NOT_ANALYZED));
            var title4 = new Field("title", "Normal Two", Field.Store.YES, Field.Index.ANALYZED);
            title4.SetBoost(2f);
            product4.Add(title4);
            product4.Add(new Field("synopsis", "special synopsis", Field.Store.YES, Field.Index.ANALYZED));

            var product5 = new Document();
            product5.Add(new Field("Id", "5", Field.Store.YES, Field.Index.NOT_ANALYZED));
            var title5 = new Field("title", "Special Three", Field.Store.YES, Field.Index.ANALYZED);
            title5.SetBoost(2f);
            product5.Add(title5);
            product5.Add(new Field("synopsis", "normal synopsis", Field.Store.YES, Field.Index.ANALYZED));

            Directory directory = FSDirectory.Open(new DirectoryInfo(Environment.CurrentDirectory + "\\Lucene"));
            Analyzer analyzer = new StandardAnalyzer();
            var writer = new IndexWriter(directory, analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);

            writer.AddDocument(product1);
            writer.AddDocument(product2);
            writer.AddDocument(product3);
            writer.AddDocument(product4);
            writer.AddDocument(product5);
            writer.Optimize();
            writer.Close();

            Console.WriteLine("searching...");
            var indexReader = IndexReader.Open(directory, true);
            var indexSearcher = new IndexSearcher(indexReader);

            var booleanQuery1 = new BooleanQuery();
            booleanQuery1.Add(new BooleanClause(new PrefixQuery(new Term("title", "special")), BooleanClause.Occur.SHOULD));
            booleanQuery1.Add(new BooleanClause(new PrefixQuery(new Term("synopsis", "special")), BooleanClause.Occur.SHOULD));

            var booleanQuery2 = new BooleanQuery();
            booleanQuery2.Add(new BooleanClause((Query)booleanQuery1, BooleanClause.Occur.MUST));
            TopDocs results = indexSearcher.Search(booleanQuery2, (Filter)null, 200);
            var hits = results.ScoreDocs;

            foreach (var hit in hits)
            {
                var document = indexSearcher.Doc(hit.doc);
                Console.WriteLine(document.Get("Id") + " " + document.Get("title") + " " + hit.score);
            }
            Console.WriteLine("done...");
            Console.ReadLine();
        }

    }   

}

Lucene バージョン 2.9.4.1 を使用しています。タイトルフィールドにブーストを設定しました。タイトルと概要フィールドで「特別」という用語を検索すると、製品 1、2、および 5 が一番上に表示されると思いますが、代わりに次の結果が得られます。

searching...
1 Special One 1.414214
2 Special Two 1.414214
3 Normal One 0.3535534
4 Normal Two 0.3535534
5 Special Three 0.3535534
done...

製品 5 のスコアは製品 3 および 4 と同じですが、そのタイトルには「特別」という用語が含まれていますが、概要には含まれていません。

どんな助けや考えもいただければ幸いです。ありがとう

4

2 に答える 2

4

問題は、PrefixQueries を使用していることだと思います。プレフィックス クエリは、一定のスコアリング クエリに書き直されます。次のように、書き換え方法を自分で設定できます。

PrefixQuery pquery = new PrefixQuery(new Term("title", "special"));
pquery.setRewriteMethod(MultiTermQuery.SCORING_BOOLEAN_QUERY_REWRITE);

または、PrefixQuery の代わりに TermQuery を使用することもできます。どちらの方法でも、フィールド レベルのブーストが有効になるはずです。

ああ、1 つ注意してください。なぜ結果がそのようにスコア付けされているのかを理解したい場合は、Searcher.explainを見てください。スコアリングは複雑になりますが、これはそれを理解して調整するための非常に便利なツールです。

于 2012-10-08T21:01:48.183 に答える
0

書籍LuceneInAction、第2版、49ページ、セクション2.5.2フィールドのブースト「ただし、フィールドまたはドキュメントのブーストを変更する場合は、ドキュメント全体を完全に削除してから読み取るか、updateDocumentを使用する必要があることに注意してください。同じことをする方法」。

同じインデックスファイルでテストしているので、インデックスを開く前にwriter.updateDocumentを呼び出す必要があると思います。

于 2012-10-08T20:59:07.103 に答える