2

Luceneで結果を返すための最小スコアを設定することは可能ですか?

私はこの機能を持っています:

public Tuple<int,ICollection<Guid>> Search(string searchQuery,int maxResults)
{
    var booleanQuery = new BooleanQuery();
    var s1 = new TermQuery(new Term("companyName", searchQuery));
    booleanQuery.Add(s1, Occur.SHOULD);

    using (var searcher = new IndexSearcher(this.Directory))
    {
        TopDocs hits = searcher.Search(booleanQuery, maxResults);

        var ids = new List<Guid>();
        for (int i = 0; i < hits.ScoreDocs.Count(); i++)
        {
            var idString = searcher.Doc(hits.ScoreDocs[i].Doc).Get("id");
            ids.Add(new Guid(idString));
        }
        return new Tuple<int, ICollection<Guid>>(hits.TotalHits, ids);
    }
}

この関数はインデックスを検索し、searchQueryに一致する会社のIDと、検索に一致した会社の総数を返します。したがって、「一致する245社のうち1〜20社を表示する」と書くことができます。

私の問題は、一致のしきい値が非常に低いことです。ユーザーが「accountant」と入力すると、検索は意味のある結果を返しますが、「adasdfsdf」と入力すると、関連性のない結果が返されます。結果の関連性が十分でない場合は、「申し訳ありませんが、クエリに一致する企業はありません」などのメッセージを表示したいと思います。

試合の最低スコアを設定することは可能ですか?TopDocs.TotalHitsプロパティはこのスコアを尊重しますか?

4

1 に答える 1

5

要するに、いいえ。Lucene で最小スコア カットオフ ポイントを実際に作成することはできません。ここでは、なぜそうしないのかについての 1 つの議論を示します。議論されているケースは、あなたが求めているものとは少し異なりますが、困難はほとんど同じであることに注意してください (実際、さまざまな独立したクエリで使用される合理的なカットオフ ポイントを提供すると、密接に関連していますが、より大きなものになります。困難)。

これに対処するより良い方法は、無関係な結果が得られないようにクエリを設計することです。あなたの例では、無関係な結果がたくさん表示される理由がよくわかりません。そのため、クエリに他の用語が追加されていると仮定します。その場合、new Term("companyName", searchQuery)一致するドキュメントのみを取得したい場合はOccur.MUST、次のように booleanClauseを使用して追加する必要があります。

var booleanQuery = new BooleanQuery();
var s1 = new TermQuery(new Term("companyName", searchQuery));
booleanQuery.Add(s1, Occur.MUST);

さらに説明すると、Occur.MUSTOccur.SHOULDが問題です。次のようなクエリがある場合:

category:type1 companyName:asdfdas

companyName に結果がない場合は、 query の結果のみが表示されますcategory:type1。companyName に一致した場合、それらの結果は関連性が高いと判断され、最初に表示されますが、カテゴリに一致するものはすべてリストのすぐ下に表示されます。この例では、両方の用語が で追加されているBooleanClause.Occur.SHOULDため、どちらもオプションです (ただし、少なくとも 1 つの一致する用語が結果に含まれている必要があります)。

カテゴリと companyName の両方に一致する用語のみを表示する場合は、BooleanClause.Occur.MUST. クエリ構文を使用すると、次のようになります。

+category:type1 +companyName:asdfdas

または、BooleanQuery を構築します。

var s1 = new TermQuery(new Term("companyName", "asdfdas"));
booleanQuery.Add(s1, Occur.MUST);
var s1 = new TermQuery(new Term("category", "type1"));
booleanQuery.Add(s1, Occur.MUST);
于 2013-02-04T18:37:16.853 に答える