5

NEST を使用して複数の bool フィルターを追加したいのですが、さまざまな条件に応じて一連のboolフィルターを作成したいので、単一のステートメントで (実際には) 実行できません。

この擬似コードのようなもの:

// Append a filter
searchDescriptor.Filter(f => f.Bool(b => b.Must(m => m.Term(i => i.SomeProperty, "SomeValue"))));

if (UserId.HasValue)
{
   // Optionally append another filter (AND condition with the first filter)
   searchDescriptor.Filter(f => f.Bool(b => b.Must(m => m.Term(i => i.AnotherProperty, "MyOtherValue"))));
}

var result = Client.Search(searchDescriptor);

2 番目のオプションのフィルターが追加されると、基本的に最初のフィルターが置き換えられるようです。

私は構文的に何かが欠けていると確信していますが、それを理解することはできません.NESTのドキュメントはフィルターDSLで少し薄いです. :)

4

2 に答える 2

12

クエリの記述に関するセクションは、フィルターにもほぼ当てはまります: https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/writing-queries.html

bool非常に異なるキャッシュメカニズムを持つフィルター内にフィルターをラップしているため、最終的なソリューションは理想的とandは言えません(フィルターはキャッシュされたビットセットを使用しないため、ほとんどの場合、通常のブールフィルターよりもパフォーマンスが低下します)。

http://www.elastic.co/blog/all-about-elasticsearch-filter-bitsets/を読むことを強くお勧めします。and/or/not フィルターと bool フィルターの違いがよく説明されています。

これを実際に次のように書き換えることができます。

Client.Search(s=>s
    .Filter(f=> { 
        BaseFilter ff = f.Term(i => i.MyProperty, "SomeValue");
        if (UserId.HasValue)
            ff &= f.Term(i => i.AnotherProperty, "AnotherValue");
        return ff;
    })
);

2 番目の用語が UserId を使用して検索している場合は、NEST を利用できます。conditionless queries

Client.Search(s=>s
    .Filter(f=> 
        f.Term(i => i.MyProperty, "SomeValue") 
        && f.Term(i => i.AnotherProperty, UserId)
    )
);

が null の場合UserId、用語クエリはクエリの一部として生成されません。この場合のネストは、残りの単一の用語を bool フィルターでラップすることさえせず、代わりに単純な用語フィルターとして送信します。

于 2013-11-03T10:42:07.130 に答える
1

ああ、このようなものがうまくいくようです:

        var filters = new List<BaseFilter>();

        // Required filter
        filters.Add(new FilterDescriptor<MyType>().Bool(b => b.Must(m => m.Term(i => i.MyProperty, "SomeValue"))));

        if (UserId.HasValue)
        {
            filters.Add(new FilterDescriptor<MyType>().Bool(b => b.Must(m => m.Term(i => i.AnotherProperty, "AnotherValue"))));
        }

        // Filter with AND operator
        searchDescriptor.Filter(f => f.And(filters.ToArray()));

        var result = Client.Search(searchDescriptor);
于 2013-10-28T17:13:43.480 に答える