我相信在这里您可能需要利用扁平值列表的优势,例如值数组。数组和嵌套对象之间的主要区别在于,后者“知道”嵌套属性的哪个值对应于数组中另一个属性的另一个值。same嵌套对象。另一方面,值数组会使某个属性的值变平,并且您会失去属性之间的“关联”client_id
and a name
。意思是,对于数组你有props.client_id = [null, 2]
and props.name = ["petlover", "premiumshopper"]
.
和你的nested
您想要将该字符串与所有值匹配的过滤器props.name
意义ALL nested props.name
一位父文档的 s 需要匹配。嗯,嵌套对象不会发生这种情况,因为嵌套文档是独立的并且是单独查询的。并且,如果至少一个嵌套文档匹配,则将其视为匹配。
换句话说,对于像这样的查询"query": "props.name:(carlover NOT petlover)"
您基本上需要针对扁平化的值列表运行它,就像数组一样。您需要针对 ["carlover", "petlover"] 运行该查询。
我给你的建议是制作嵌套文档"include_in_parent": true
(意思是,在父级中保留一个扁平的、类似数组的值列表)并稍微更改一下查询:
- for the
query_string
部分,使用扁平属性方法能够匹配元素组合列表的查询,而不是逐个元素。
- for the
match
(or term
,见下文)和missing
部件使用嵌套属性方法,因为您可以有null
在那里。 Amissing
仅当整个数组丢失而不是其中缺少一个值时,数组上的内容才会匹配,因此这里不能使用与查询相同的方法,其中值在数组中被展平。
- 可选,但对于
query
match
我会使用的整数term
,因为它不是字符串而是整数,并且默认情况下是not_analyzed
.
话虽这么说,经过上述更改,这些更改是:
{
"mappings" : {
...
"props": {
"type": "nested",
"include_in_parent": true,
...
- 应该(并且确实)返回零结果
GET /nesting-test/_search?pretty=true
{
"query": {
"filtered": {
"filter": {
"and": [
{
"query": {
"query_string": { "query": "props.name:((carlover AND premiumshopper) NOT petlover)" }
}
},
{
"nested": {
"path": "props",
"filter": {
"or": [ { "query": { "match": { "props.client_id": 1 } } }, { "missing": { "field": "props.client_id" } } ]
}
}
}
]
}
}
}
}
- 应该(并且确实)只返回 1
GET /nesting-test/_search?pretty=true
{
"query": {
"filtered": {
"filter": {
"and": [
{"query": {"query_string": { "query": "props.name:(carlover NOT petlover)" } } },
{
"nested": {
"path": "props",
"filter": {
"or": [{ "query": { "match": { "props.client_id": 1 } } },{ "missing": { "field": "props.client_id" } } ]
}
}
}
]
}
}
}
}
- 应该(并且确实)只返回 2
GET /nesting-test/_search?pretty=true
{
"query": {
"filtered": {
"filter": {
"and": [
{ "query": {"query_string": { "query": "props.name:(* NOT carlover)" } } },
{
"nested": {
"path": "props",
"filter": {
"or": [{ "query": { "term": { "props.client_id": 1 } } },{ "missing": { "field": "props.client_id" } }
]
}
}
}
]
}
}
}
}