6

私には興味深い課題があり、簡単な答えがあると思います。

構文的に次のようなことを行うと、NEST フィルターが正しく機能することがわかっています。

var andFilter = FilterFactory.AndFilter(
                    FilterFactory.TermFilter("name.first", "shay1"),
                    FilterFactory.TermFilter("name.first", "shay4")
                );

私の基本サービスでは、発信者が何らかの列挙可能なアイテムのリストを渡してフィルタリングできるようにする必要があります。

私は基本的に、プログラムで次のようなことを達成できるようにしたいと考えています(フィルターはメソッドに渡されます):

var andFilter = new FilterDescriptor();
foreach (var filter in filters) 
{
     andFilter = filter concatenated to andFilter
}

つまり、{ {"first.name", "joe"}, {"first.name", "jim"}, {"first.name", "frank"}} の配列を渡した場合、に相当するものを生成する

var andFilter = FilterFactory.AndFilter(
                    FilterFactory.TermFilter("name.first", "joe"), 
                    FilterFactory.TermFilter("name.first", "joe"),
                    FilterFactory.TermFilter("name.first", "frank")
                );
4

3 に答える 3

9

ラムダベースの DSL を使用すると、次のことができます。

var termsFilters = from tp in termParameters
                   let field = ToCamelCaseNestedNames(tp.SearchField)
                   let terms = tp.SearchValues
                   select Filter.Terms(field, terms);

var prefixFilters = from tp in prefixParameters
                    let field = ToCamelCaseNestedNames(tp.SearchField)
                    let prefix = tp.SearchValues.FirstOrDefault().ToLowerInvariant()
                    select Filter.Prefix(field, prefix);

var search = client.Search(s => s
    .From(0)
    .Size(20)
    .Filter(f => f.And(termsFilters.Concat(prefixFilters).ToArray()))
);

どちらが読みやすいと思います:)

Nest はクエリもサポートするようになったため、 、またはがconditionlessあれば、その用語/プレフィックス クエリはスキップされます。tp.SearchValuesnullemptyall empty stringstp.SearchFieldnull or empty

ただし、この動作は簡単に元に戻すことができます。

var search = client.Search(s => s
    .Strict()
    .From(0)
    .Size(20)
    .Filter(f => f.And(termsFilters.Concat(prefixFilters).ToArray()))
);

DslException空のクエリが生成された場合にスローされます。

最後のメモとして、ドキュメントを厳密に入力できる場合はclient.Search()a が返されるので、a を実行できます。QueryResult<dynamic>client.Search<MyDocument>()

于 2012-12-02T20:53:49.100 に答える
1

Martijnの答えは最高ですが、私が作成した例を追加すると思いました。うまくいけば、他の人に役立つでしょう。BaseQuery オブジェクトのリストを作成し、それを .ToArray() メソッドを使用してクエリに入れました。

    #region build query

    var query = new List<BaseQuery>
                {
                    Query<IAuthForReporting>.Range(r => r.OnField(f => f.AuthResult.AuthEventDate)
                                                    .From(authsByDateInput.StartDate.ToEPCISFormat())
                                                    .To(authsByDateInput.EndDate.ToEPCISFormat()))
                };
    if (authsByDateInput.AuthResult != AuthResultEnum.SuccessOrFailure)
    {
        var success = authsByDateInput.AuthResult == AuthResultEnum.Success;
        query.Add(Query<IAuthForReporting>.Term(t => t.AuthResult.AuthenticationSuccessful, success));
    }
    if (authsByDateInput.ProductID != null)
    {
        query.Add(Query<IAuthForReporting>.Term(t => t.AuthResult.ProductID, authsByDateInput.ProductID.Value));
    }

    if (!authsByDateInput.CountryIDs.IsNullOrEmpty())
    {
        query.Add(Query<IAuthForReporting>.Terms(t => t.AuthResult.Address.CountryID, authsByDateInput.CountryIDs.Select(x=> x.Value.ToString()).ToArray()));
    }
    #endregion

        var result =
            ElasticClient.Search<IAuthForReporting>(s =>
                                                    s.Index(IndexName)
                                                     .Type(TypeName)
                                                     .Size(0)
                                                     .Query(q =>
                                                            q.Bool(b =>
                                                                   b.Must(query.ToArray())
                                                                )
                                                        )
                                                     .FacetDateHistogram(t => t.OnField(f => f.AuthResult.AuthEventDate).Interval(DateInterval.Day))
                );
于 2014-03-04T15:02:11.470 に答える
-1

この件について研究開発を行った結果、次のような問題を解決することができました。AndおよびOrのサポートについて追加の作業を行う必要があります。

        IList<IFilterBuilder> conditions = new List<IFilterBuilder>();
        if (termParameters != null)
            foreach (var termParameter in termParameters)
                conditions.Add(FilterFactory.TermsFilter(ToCamelCaseNestedNames(termParameter.SearchField), termParameter.SearchValues));

        if (prefixParameters != null)
            foreach (var prefixParameter in prefixParameters)
                conditions.Add(FilterFactory.PrefixFilter(ToCamelCaseNestedNames(prefixParameter.SearchField), prefixParameter.SearchValues.First().ToLowerInvariant()));

        var filters = FilterFactory.AndFilter();
        filters.Add(FilterFactory.AndFilter(conditions.ToArray()));

        MatchAllQueryBuilder matchAllQueryBuilder = new MatchAllQueryBuilder();
        FilteredQueryBuilder filteredQueryBuilder = new FilteredQueryBuilder(matchAllQueryBuilder, filters);
        SearchBuilder searchBuilder = new SearchBuilder();
        searchBuilder.Query(filteredQueryBuilder);
        searchBuilder.Size(maxResults);
于 2012-11-19T14:38:26.237 に答える