1

次のデータを取得して、以下の結果を得るにはどうすればよいですか?

コード サンプルを含めましたが、複数の列を適切に検索して必要なブーストを適用する方法がわかりません。

私はこれを正しい方法で行っていますか?

各列のブースト/重み

First Name = 100

Last Name = 75

Bio = 50

データ

名、姓、略歴
Benny, Benson, This is a test

- "ben" appears in the first name AND last name

- Score = 175

Jim, Smith, Another test with the word ben

- "ben" appears in the bio

- Score = 50

John, Benson, And another test here

- "ben" appears in the last name

- Score = 75

結果

1. Benny
2. John
3. Jim

protected override void _addToLuceneIndex(dynamic item, IndexWriter writer)
{
    var user = item as UserTestItem;
    if (user == null) return;

    // remove older index entry
    var searchQuery = new TermQuery(new Term(USER_ID, user.UserID.ToString(CultureInfo.InvariantCulture)));
    writer.DeleteDocuments(searchQuery);

    // add new index entry
    var doc = new Document();

    // get fields
    var userId = new Field(USER_ID, user.UserID.ToString(CultureInfo.InvariantCulture), Field.Store.YES, Field.Index.NOT_ANALYZED);
    var firstName = new Field(FIRST_NAME, user.FirstName ?? string.Empty, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES);
    var lastName = new Field(LAST_NAME, user.LastName ?? string.Empty, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES);
    var bio = new Field(BIO, user.Bio ?? string.Empty, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES);

    // add boosts
    firstName.Boost = 100f;
    lastName.Boost = 75f;
    bio.Boost = 50f;

    // add lucene fields mapped to db fields
    doc.Add(userId);
    doc.Add(firstName);
    doc.Add(lastName);
    doc.Add(bio);

    // add entry to index
    writer.AddDocument(doc);
}

public string[] FieldsToSearch { get; set; } // i.e. "FirstName", "LastName", "Bio"

public UserSearchResults SearchUsers(string searchQuery, bool exact = false)
{
    var results = new UserSearchResults();

    if (!string.IsNullOrEmpty(searchQuery))
    {
        //searchQuery = PrepareInput(searchQuery, exact);

        try
        {
            using (var searcher = new IndexSearcher(IndexDirectory, false))
            {
                var analyzer = new StandardAnalyzer(LUCENE_VERSION);

                // Search by multiple fields (ordered by RELEVANCE)
                var parser = new MultiFieldQueryParser(LUCENE_VERSION, FieldsToSearch, analyzer);
                parser.AllowLeadingWildcard = true;
                parser.DefaultOperator = exact ? QueryParser.AND_OPERATOR : QueryParser.OR_OPERATOR;

                var multiFieldQuery = ParseQuery(searchQuery, parser);

                var hits = searcher.Search(multiFieldQuery, null, SearchResultLimit, Sort.RELEVANCE);
                var docs = hits.ScoreDocs;

                results.Items = _mapLuceneToDataList(docs, searcher).Cast<UserTestItem>().ToList();
                results.Total = results.Items.Count;

                results.RawQuery = LastUsedQuery.ToString();

                analyzer.Close();
                searcher.Dispose();
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
        }
    }

    return results;
}
4

3 に答える 3

2

ブーストを MultiFieldQueryParser に直接渡すことができます。例:

var boosts = new Dictionary<string, float>
{
    {"First Name", 100},
    {"Last Name", 75},
    {"Bio", 50},
}
var parser = new MultiFieldQueryParser(LUCENE_VERSION, FieldsToSearch, analyzer, boosts);
于 2014-12-04T12:31:50.353 に答える
0

Boost は Lucene のアルゴリズムでは失われるため、Boost と検索語が混在しています。一連の一致を返す必要がある別のオプション (つまり、Kevin Smith で検索) で、類似性/Lucene のスコアに基づいて 50 の一致があります。次に、追加のフィールドをデータベースで計算してフィールドで並べ替え、LINQ を使用して Lucene コレクターからの結果を並べ替えます。これはブースティングとは少し異なりますが、正確なスコアと並べ替えをより細かく制御できます。

于 2013-08-18T15:45:27.320 に答える
0

私は今、私が望む行動を持っていると信じています。私が行っていたインデックス作成中にブーストするのではなく、このようにクエリをブーストする必要がありました。

var mainQuery = new BooleanQuery();

var fnQuery = new BooleanQuery();
fnQuery.Add(new WildcardQuery(new Term(FIRST_NAME, searchQuery)), Occur.SHOULD);
fnQuery.Boost = 100f;

var lnQuery = new BooleanQuery();
lnQuery.Add(new WildcardQuery(new Term(LAST_NAME, searchQuery)), Occur.SHOULD);
lnQuery.Boost = 75f;

var bioQuery = new BooleanQuery();
bioQuery.Add(new WildcardQuery(new Term(BIO, searchQuery)), Occur.SHOULD);
bioQuery.Boost = 50f;

mainQuery.Add(fnQuery, Occur.SHOULD);
mainQuery.Add(lnQuery, Occur.SHOULD);
mainQuery.Add(bioQuery, Occur.SHOULD);

var hits = searcher.Search(mainQuery, null, SearchResultLimit, Sort.RELEVANCE);

これを行うより適切な方法はありますか?

于 2013-08-16T01:50:43.210 に答える