术语,嵌套文档和must_not查询在ElasticSearch中不兼容?

use*_*203 8 nested term elasticsearch

我在嵌套文档上组合term,must_not查询时遇到问题.

感觉的例子可以在这里找到:http://sense.qbox.io/gist/be436a1ffa01e4630a964f48b2d5b3a1ef5fa176

这是我的映射:

{
    "mappings": {
        "docs" : {
            "properties": {
                "tags" : {
                    "type": "nested",
                    "properties" : {
                        "type": {
                           "type": "string",
                           "index": "not_analyzed"
                        }
                    }
                },
                "label" : {
                    "type": "string"
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此索引中包含两个文档:

{
    "tags" : [
        {"type" : "POST"},
        {"type" : "DELETE"}
    ],
    "label" : "item 1"
},
{
    "tags" : [
        {"type" : "POST"}
    ],
    "label" : "item 2"
}
Run Code Online (Sandbox Code Playgroud)

当我像这样查询这个索引时:

{
  "query": {
    "nested": {
      "path": "tags",
      "query": {
        "bool": {
          "must": {
            "term": {
              "tags.type": "DELETE"
            }
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我有一击(这是正确的)

当我想要获取不包含标签"DELETE"的文档时,使用此查询:

{
  "query": {
    "nested": {
      "path": "tags",
      "query": {
        "bool": {
          "must_not": {
            "term": {
              "tags.type": "delete"
            }
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我有2次点击(这是不正确的). 这个问题似乎非常接近这个问题(Elasticsearch数组必须且必须没有),但它不是......

你能给我一些解决这个问题的线索吗?

谢谢

rvh*_*deg 16

您的原始查询将搜索每个单独的嵌套对象并消除不匹配的对象,但如果剩下一些嵌套对象,它们会与您的查询匹配,从而获得结果.这是因为嵌套对象被索引为隐藏的单独文档

原始代码:

{
  "query": {
    "nested": {
      "path": "tags",
      "query": {
        "bool": {
          "must_not": {
            "term": {
              "tags.type": "delete"
            }
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

那么解决方案非常简单,你应该将bool查询带到嵌套文档之外.现在丢弃所有具有" DELETE "类型的嵌套对象的文档.正是你想要的!

解决方案:

{
  "query": {
    "bool": {
      "must_not": {
        "nested": {
          "path": "tags",
          "query": {
            "term": {
              "tags.type": "DELETE"
            }
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

注意:您的字符串"未分析",您搜索"删除"而不是"删除".如果要搜索不区分大小写,请对字符串进行分析


Ben*_*.io 1

这应该可以解决您的问题: http://sense.qbox.io/gist/f4694f542bc76c29624b5b5c9b3ecdee36f7e3ea

最重要的两件事:

  1. include_in_root 在“tags.type”上。这将告诉 ES 将标签类型索引为"doc.tags.types" : ['DELETE', 'POSTS'],因此您可以访问根文档上“扁平化”的这些值的数组。这意味着您不再需要嵌套查询(参见#2)

  2. 删除嵌套查询。

 

{
    "mappings": {
        "docs" : {
            "properties": {
                "tags" : {
                    "type": "nested",
                    "properties" : {
                        "type": {
                           "type": "string",
                           "index": "not_analyzed"
                        }
                    },
                    "include_in_root": true
                },
                "label" : {
                    "type": "string"
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

 

{
   "query": {
      "bool": {
         "must_not": {
            "term": {
               "tags.type": "DELETE"
            }
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)