我必须使用Nest查询嵌套对象,但查询是以动态方式构建的。下面的代码演示了如何在嵌套" books"上使用查询。以静态的方式
QueryContainer qry;
qry = new QueryStringQuery()
{
DefaultField = "name",
DefaultOperator = Operator.And,
Query = "salman"
};
QueryContainer qry1 = null;
qry1 = new RangeQuery() // used to search for range ( from , to)
{
Field = "modified",
GreaterThanOrEqualTo = Convert.ToDateTime("21/12/2015").ToString("dd/MM/yyyy"),
};
QueryContainer all = qry && qry1;
var results = elastic.Search<Document>(s => s
.Query(q => q
.Bool(qb => qb
.Must(all)))
.Filter(f =>
f.Nested(n => n
.Path("books")
.Filter(f3 => f3.And(
f1 => f1.Term("book.isbn", "122"),
f2 => f2.Term("book.author", "X"))
)
)
)
);
问题在于我需要将多个查询(使用And,OR运算符)组合成&#34; books&#34;以动态的方式。例如,获取满足这些条件的书籍:
现在,嵌套查询中的过滤器应该在以下情况下检索书籍:
条件1 AND 条件2 或条件3
假设我有类名FilterOptions,它包含以下属性:
我将循环使用给定的FilterOptions数组来构建查询。
问题:
我应该使用什么来构建嵌套查询?它是一个FilterDesciptor,如何组合它们将嵌套查询添加到搜索方法?
请推荐任何有价值的链接或示例?
答案 0 :(得分:11)
我同意paweloque,看来你的前两个条件是相互矛盾的,如果和它们在一起就行不通。忽略这一点,这是我的解决方案。我已经实现了这种方式,允许超过你拥有的三个特定条件。我也觉得它在bool
陈述中更适合。
QueryContainer andQuery = null;
QueryContainer orQuery = null;
foreach(var authorFilter in FilterOptions.Where(f=>f.Operator==Operator.And))
{
andQuery &= new TermQuery
{
Field = authorFilter.FieldName,
Value = authorFilter.Value
};
}
foreach(var authorFilter in FilterOptions.Where(f=>f.Operator==Operator.Or))
{
orQuery |= new TermQuery
{
Field = authorFilter.FieldName,
Value = authorFilter.Value
};
}
之后,在.Nested
电话中,我会说:
.Path("books")
.Query(q=>q
.Bool(bq=>bq
.Must(m=>m.MatchAll() && andQuery)
.Should(orQuery)
))
答案 1 :(得分:1)
在Condition 1
和Condition 2
的特定情况下,您可能无法获得任何结果,因为这些是排他性条件。但我现在假设,您希望获得与这些条件相匹配的结果。你已经选择了嵌套,这绝对是你要走的路。使用嵌套类型,您可以组合单个书籍的参数。
合并嵌套查询
对于您的用例,我会使用bool
或must
条款的should
查询类型。
获取Condition 1
或Condition 2
图书的查询将是:
POST /books/_search
{
"query": {
"bool": {
"should": [
{
"nested": {
"path": "books",
"query": {
"bool": {
"must": [
{
"match": {
"books.isbn": "2"
}
},
{
"match": {
"books.author": "X"
}
}
]
}
}
}
},
{
"nested": {
"path": "books",
"query": {
"bool": {
"must": [
{
"match": {
"books.isbn": "1"
}
},
{
"match": {
"books.author": "X"
}
}
]
}
}
}
}
]
}
}
}
你能解释一下,为什么你的书被嵌套了?如果不将它们嵌套在顶部结构中,而是直接索引为索引/类型中的顶级对象,则可以简化查询。
不会-分析强>
还有一点需要提醒您:如果您希望与作者和ISBN完全匹配,则必须确保ISBN和作者字段设置为not_analyzed
。否则,他们会被分析并分成几部分,你的匹配将无法正常工作。
E.g。如果你有一个带破折号的ISBN号,那么它会分成几部分:
978-3-16-148410-0
将被编入索引:
978
3
16
148410
0
具有完全相同ISBN号的搜索将为您提供其ISBN号中包含其中一个子编号的所有图书。如果您想阻止这种情况,请使用not_analyzed
索引类型和Multi-fields:
"isbn": {
"type": "string",
"fields": {
"raw": {
"type": "string",
"index": "not_analyzed"
}
}
}
然后,要解决not_analyzed
isbn字段,您必须调用它:
books.isbn.raw
希望这有帮助。