lovelmh13 / myBlog

个人博客 记录菜狗的学习之路
6 stars 0 forks source link

keyword #125

Open lovelmh13 opened 3 years ago

lovelmh13 commented 3 years ago

在 es 中,对词进行查询、聚合的时候,需要使用 .keyword。 否则会报错:

Text fields are not optimised for operations that require per-document field data like aggregations and sorting, so these operations are disabled by default. Please use a keyword field instead. Alternatively, set fielddata=true on [content.resource.name] in order to load field data by uninverting the inverted index.

使用 keyword 查询如下:

"terms": {
    "field": "content.resource.name.keyword"
}

什么是 keyword

1.ES5.0 及以后的版本取消了 string 类型,将原先的 string 类型拆分为 text 和 keyword 两种类型。它们的区别在于 text 会对字段进行分词处理而 keyword 则不会。 2.当你没有以 IndexTemplate 等形式为你的索引字段预先指定 mapping 的话,ES 就会使用 Dynamic Mapping,通过推断你传入的文档中字段的值对字段进行动态映射。例如传入的文档中字段 price 的值为 12,那么 price 将被映射为 long 类型;字段 addr 的值为"192.168.0.1",那么 addr 将被映射为 ip 类型。然而对于不满足 ip 和 date 格式的普通字符串来说,情况有些不同:ES 会将它们映射为 text 类型,但为了保留对这些字段做精确查询以及聚合的能力,又同时对它们做了 keyword 类型的映射,作为该字段的 fields 属性写到 _mapping 中。例如,当ES遇到一个新的字段 "foobar": "some string" 时,会对它做如下的 Dynamic Mapping : { "foobar": { "type" "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } 在之后的查询中使用 foobar 是将 foobar 作为 text 类型查询,而使用 foobar.keyword 则是将 foobar 作为 keyword 类型查询。前者会对查询内容做分词处理之后再匹配,而后者则是直接对查询结果做精确匹配。 3.ES 的 term query 做的是精确匹配而不是分词查询,因此对 text 类型的字段做 term 查询将是查不到结果的(除非字段本身经过分词器处理后不变,未被转换或分词)。此时,必须使用 foobar.keyword 来对 foobar 字段以 keyword 类型进行精确匹配。

总结: 使用 term 进行精确词的匹配的时候,必须要用 keyword