1

検索機能を変換して、複数の単語を含むあいまい検索を許可しようとしています。私の既存の検索コードは次のようになります。

        // Split the search into seperate queries per word, and combine them into one major query
        var finalQuery = new BooleanQuery();

        string[] terms = searchString.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string term in terms)
        {
            // Setup the fields to search
            string[] searchfields = new string[] 
            {
                // Various strings denoting the document fields available
            };

            var parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, searchfields, new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
            finalQuery.Add(parser.Parse(term), BooleanClause.Occur.MUST);
        }

        // Perform the search
        var directory = FSDirectory.Open(new DirectoryInfo(LuceneIndexBaseDirectory));
        var searcher = new IndexSearcher(directory, true);
        var hits = searcher.Search(finalQuery, MAX_RESULTS);

これは正しく機能し、「My name is Andrew」という名前フィールドを持つエンティティがあり、「Andrew Name」の検索を実行すると、Lucene は正しいドキュメントを正しく見つけます。「Anderw Name」が正しく見つかるように、あいまい検索を有効にしたいと思います。次のコードを使用するようにメソッドを変更しました。

        const int MAX_RESULTS = 10000;
        const float MIN_SIMILARITY = 0.5f;
        const int PREFIX_LENGTH = 3;

        if (string.IsNullOrWhiteSpace(searchString))
            throw new ArgumentException("Provided search string is empty");

        // Split the search into seperate queries per word, and combine them into one major query
        var finalQuery = new BooleanQuery();

        string[] terms = searchString.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string term in terms)
        {
            // Setup the fields to search
            string[] searchfields = new string[] 
            {
                // Strings denoting document field names here
            };

            // Create a subquery where the term must match at least one of the fields
            var subquery = new BooleanQuery();
            foreach (string field in searchfields)
            {
                var queryTerm = new Term(field, term);
                var fuzzyQuery = new FuzzyQuery(queryTerm, MIN_SIMILARITY, PREFIX_LENGTH);
                subquery.Add(fuzzyQuery, BooleanClause.Occur.SHOULD);
            }

            // Add the subquery to the final query, but make at least one subquery match must be found
            finalQuery.Add(subquery, BooleanClause.Occur.MUST);
        }

        // Perform the search
        var directory = FSDirectory.Open(new DirectoryInfo(LuceneIndexBaseDirectory));
        var searcher = new IndexSearcher(directory, true);
        var hits = searcher.Search(finalQuery, MAX_RESULTS);

残念ながら、このコードを使用して検索クエリ「Andrew Name」を送信すると (前と同じ)、結果が返されません。

核となる考え方は、すべての用語が少なくとも 1 つのドキュメント フィールドに存在する必要があるということですが、各用語は異なるフィールドに存在することができます。書き換えられたクエリが失敗する理由を誰かが知っていますか?


最終編集:わかりました、私はこれをかなり複雑にしすぎていたことがわかりました.最初のアプローチから変更する必要はありませんでした. 最初のコード スニペットに戻った後、変更してあいまい検索を有効にしました。

finalQuery.Add(parser.Parse(term), BooleanClause.Occur.MUST);

finalQuery.Add(parser.Parse(term.Replace("~", "") + "~"), BooleanClause.Occur.MUST);
4

2 に答える 2

3

searchStringを小文字に書き換えると、コードが機能します。when インデックスを使用していると仮定するとStandardAnalyzer、小文字の用語が生成されます。

1) トークンを同じアナライザーに渡す (同一の処理を可能にする)、2) アナライザーと同じロジックを適用する、または 3) 実行する処理に一致するアナライザーを使用する ( WhitespaceAnalyzer) 必要があります。

于 2011-05-26T03:53:47.627 に答える
1

この行が必要です:

var queryTerm = new Term(term);

次のようになります。

var queryTerm = new Term(field, term);

現在term、空の文字列 (決して見つからない) のフィールド (おそらく存在しない) を検索しています。

于 2011-05-25T17:57:58.183 に答える