2014-03-07 196 views
6

我无法在嵌套文档中组合term,must_not查询。ElasticSearch中的术语,嵌套文档和must_not查询不兼容?

意识例子可以在这里找到:http://sense.qbox.io/gist/be436a1ffa01e4630a964f48b2d5b3a1ef5fa176

这里我映射:

{ 
    "mappings": { 
     "docs" : { 
      "properties": { 
       "tags" : { 
        "type": "nested", 
        "properties" : { 
         "type": { 
          "type": "string", 
          "index": "not_analyzed" 
         } 
        } 
       }, 
       "label" : { 
        "type": "string" 
       } 
      } 
     } 
    } 
} 

在此指数两个文件:

{ 
    "tags" : [ 
     {"type" : "POST"}, 
     {"type" : "DELETE"} 
    ], 
    "label" : "item 1" 
}, 
{ 
    "tags" : [ 
     {"type" : "POST"} 
    ], 
    "label" : "item 2" 
} 

当我询问该指数是这样的:

{ 
    "query": { 
    "nested": { 
     "path": "tags", 
     "query": { 
     "bool": { 
      "must": { 
      "term": { 
       "tags.type": "DELETE" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

我有一重击(这是正确的)

当我想不包含标签“删除”的文件,该查询:

{ 
    "query": { 
    "nested": { 
     "path": "tags", 
     "query": { 
     "bool": { 
      "must_not": { 
      "term": { 
       "tags.type": "delete" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

我已经有2次点击(这是不正确的)。 这个问题看起来非常接近这个(Elasticsearch array must and must_not),但它不是...

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

谢谢

回答

0

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

两个最重要的事情:在 “tags.type”

  1. include_in_root。这将告诉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" 
       } 
      } 
     } 
    } 
} 

 

{ 
    "query": { 
     "bool": { 
     "must_not": { 
      "term": { 
       "tags.type": "DELETE" 
      } 
     } 
     } 
    } 
} 
+0

谢谢,它的工作原理。你能解释你为什么这么做吗? – user3393203

+0

仅仅因为它没有“include_in_root”是不可能的。现在,您可以将所有“tags.type”视为一个数组,而不是拥有复杂的嵌套过滤器/查询系统。这样,你可以说“像给我所有的文档没有在标签类型数组中的'DELETE'”。 有时候很难说出这些东西,但希望这是有道理的! –

+0

它不适合我。这既奇怪又伤心。这可能是因为我使用'terms'和'integer'? –

9

你原来的查询将在每个单独的嵌套的对象搜索和消灭谁不同意这些对象,但如果有一些嵌套的对象左边,他们同意你的查询,所以你得到你的结果。这是因为,嵌套的对象是索引作为隐藏单独的文件

原始代码:

{ 
    "query": { 
    "nested": { 
     "path": "tags", 
     "query": { 
     "bool": { 
      "must_not": { 
      "term": { 
       "tags.type": "delete" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

然后将溶液真的很简单,你应该把布尔查询嵌套的文件之外。现在所有文档都被丢弃,其中嵌套对象的类型为“DELETE”。正是你想要的!

解决办法:

{ 
    "query": { 
    "bool": { 
     "must_not": { 
     "nested": { 
      "path": "tags", 
      "query": { 
      "term": { 
       "tags.type": "DELETE" 
      } 
      } 
     } 
     } 
    } 
    } 
} 

注:您的字符串“不分析”,然后搜索“删除”,而不是“删除”。如果你想搜索不区分大小写,请分析你的字符串

+0

如果我这样做,没有标签字段的数据不包含在结果中 –

+0

您确定吗?你使用哪个Elasticsearch版本? – rvheddeg

+0

ElasticSearch 2.2.1。重新检查后,很多查询在我的笔记本电脑上正常工作,但在服务器中正常工作。 Elasticsearch版本可能发挥作用。 –