具有动态匹配的 ElasticSearch 嵌套查询

ElasticSearch Nest Query with Dynamic Match

我想使用条件匹配动态构建 ElasticSearch Nest SearchDescriptor。 UI 有两个复选框 "Exclude Email" 和 "Exclude Loose Files"。如果两者都勾选,则搜索结果匹配0条。

这 4 个查询有效,但我不知道如何根据条件使匹配部分动态化(除了为 UI 复选框的每个排列设置 'if-elseif-else' 语句之外).

感谢您提出任何建议。

                var searchDescriptor = new SearchDescriptor<MyDocument>()
                        .Query(q => q
                            .Match(m => m.OnField(p => p.isemail).Query("true"))
                            && q.Match(m => m.OnField(p => p.isemail).Query("false"))
                            && q.QueryString(p => p.Query(searchParameters.query).DefaultOperator(Operator.And))
                            && q.Term(p => p.Author, searchParameters.author == null ? null : searchParameters.author.ToLower())
                        );

                var searchDescriptor = new SearchDescriptor<MyDocument>()
                        .Query(q => q
                            .Match(m => m.OnField(p => p.isemail).Query("true"))
                            && q.QueryString(p => p.Query(searchParameters.query).DefaultOperator(Operator.And))
                            && q.Term(p => p.Author, searchParameters.author == null ? null : searchParameters.author.ToLower())
                        );

                var searchDescriptor = new SearchDescriptor<MyDocument>()
                        .Query(q => q
                            .Match(m => m.OnField(p => p.isemail).Query("false"))
                            && q.QueryString(p => p.Query(searchParameters.query).DefaultOperator(Operator.And))
                            && q.Term(p => p.Author, searchParameters.author == null ? null : searchParameters.author.ToLower())
                        );

                var searchDescriptor = new SearchDescriptor<MyDocument>()
                        .Query(q => q
                            .QueryString(p => p.Query(searchParameters.query).DefaultOperator(Operator.And))
                            && q.Term(p => p.Author, searchParameters.author == null ? null : searchParameters.author.ToLower())
                        );

有多种方法可以将各种调用合并为一个调用,根据布尔输入 return 会产生不同的结果。

你有 2 个变量和 4 个不同的结果,你必须在某个地方实现检查所有这些的逻辑,所以你用 SearchDescriptors 构建了 if/elseif/else 块,但是使用嵌套过滤器这会变得更优雅(尽管仍然相似)。如果需要更改,以下带有过滤器的内容将更容易在以后进行修改,并且比大的 if/else 块更具可读性。

Func<FilterDescriptor<T>, FilterContainer> filterName = null;

if (foo && bar) { 

filterName = af => af.Query(
    q => q.Match(m => m.OnField(p => p.isemail).Query("true")) && 
    q.Match(m => m.OnField(p => p.isemail).Query("false"))
)}

if (foo) {
filterName = af => af.Query(
    q => q.Match(m => m.OnField(p => p.isemail).Query("true"))
)}

if (bar) {
filterName = af => af.Query(
    q => q.Match(m => m.OnField(p => p.isemail).Query("false"))
)}

//Any Filter that will always return true, so Filter != null
else {filterName = af => af.Exists("id");}

使用过滤器创建您的搜索描述符。只有满足过滤器要求的结果才会 return。 Elasticsearch 会排除不符合过滤器要求的项目 before 运行 你的查询,这一点要记住。

var searchDescriptor = new SearchDescriptor<MyDocument>()
    .Query(q => q
        .QueryString(p => p.Query(searchParameters.query).DefaultOperator(Operator.And))
        && q.Term(p => p.Author, searchParameters.author == null ? null : searchParameters.author.ToLower())
    ).Filter(filterName);