我有一个对象映射,它以类似标签的方式使用嵌套对象(在我们的示例中为props
)。
每个标记都属于客户端/用户,并且我们希望允许用户针对query_string
生成props.name
样式搜索。
问题在于,当我们运行查询时,如果一个对象有多个道具,并且当其他人不知道该对象返回时,其中一个道具匹配过滤器,当我们想要相反时 - 如果一个返回false don& #39; t返回vs.如果一个返回真实的回报。
我在这里发布了一个全面的例子:https://gist.github.com/d2kagw/1c9d4ef486b7a2450d95
提前致谢。
答案 0 :(得分:1)
我相信你可能需要一个扁平的值列表的优势,比如值数组。数组和嵌套对象之间的主要区别在于后者"知道"嵌套属性的哪个值对应于相同嵌套对象中另一个属性的另一个值。另一方面,值数组会使某个属性的值变平并且会失去"关联"在client_id
和name
之间。意思是,对于数组,您有props.client_id = [null, 2]
和props.name = ["petlover", "premiumshopper"]
。
使用nested
过滤器,您希望将该字符串与props.name
的所有值匹配,这意味着所有一个父文档的嵌套props.name
需要匹配。好吧,嵌套对象不会发生这种情况,因为嵌套文档是分开的并且是单独查询的。并且,如果至少有一个嵌套文档匹配,那么它被视为匹配。
换句话说,对于像"query": "props.name:(carlover NOT petlover)"
这样的查询,你基本上需要针对一个扁平的值列表运行它,就像数组一样。您需要针对[" carlover"," petlover"]运行该查询。
我的建议是制作嵌套文档"include_in_parent": true
(意思是,在父级中保留一个扁平的,类似数组的值列表)并更改一下查询:
query_string
部分,使用展平属性方法,以便能够将您的查询与元素的组合列表进行匹配,而不是逐个元素。match
(或term
,见下文)和missing
部分使用嵌套属性方法,因为您可以拥有null
。数组上的missing
只有在缺少整个数组时才匹配,而不是其中的一个值,所以这里不能使用与查询相同的方法,其中值在数组中展平。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" } } ]
}
}
}
]
}
}
}
}
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" } } ]
}
}
}
]
}
}
}
}
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" } }
]
}
}
}
]
}
}
}
}