什么是 ES Nested 嵌套类型? Elasticsearch 有很多数据类型,大致如下:
- 基本数据类型: string 类型。ES 7.x 中,string 类型会升级为:text 和 keyword。keyword 可以排序;text 默认分词,不可以排序。
- 数据类型:integer、long 等
- 时间类型、布尔类型、二进制类型、区间类型等
- 复杂数据类型:
- 数组类型:Array
- 对象类型:Object Nested 类型
- 特定数据类型:地理位置、IP 等 注意:tring/nested/array 类型字段不能用作排序字段。因此 string 类型会升级为:text 和 keyword。keyword 可以排序,text 默认分词,不可以排序。
nested 类型是一种特殊的 [object,object] 类型. 这种类型允许对 object 数组内的元素进行单独查询,区别是:
- object: Lucene 没有内部 object 的概念, 所以 Elasticsearch 内部会把 object 解析成简单的字段名与值的信息,就是所有字段平铺。
- nested: Elasticsearch 内部会把数组中的每个元素当成一个隐藏文档, 所以可以用 [query-dsl-nested-query,nested query]
嵌套模型的优缺点如下:
- 文档存储在一起,因此读取性能高
- 如果新增丶修改或删除一个嵌套文档,则必须重新索引整个文档。因此越多嵌套文档造成越多的成本。
动态映射 字段数据类型不需要事先定义,ES内部自动映射默认字段类型。如果是object类型,数据同步时会把内部的text映射成text,还会带上keyowd的子类型。参考
嵌套类型搜索
object类型的filed会把text类型字段没有加上keyword,就是不分词。所以我们改成neatest类型。 因嵌套对象(nested objects)会被索引为分离的隐藏文档,我们不能直接查询它们。而是使用 nested查询或 nested 过滤器来存取它们:
GET /my_index/blogpost/_search
{
"query": {
"bool": {
"must": [
{ "match": { "title": "eggs" }}, <1>
{
"nested": {
"path": "comments", <2>
"query": {
"bool": {
"must": [ <3>
{ "match": { "comments.name": "john" }},
{ "match": { "comments.age": 28 }}
]
}}}}
]
}}}
嵌套字段排序问题
PUT /my_index/blogpost/2
{
"title": "Investment secrets",
"body": "What they don't tell you ...",
"tags": [ "shares", "equities" ],
"comments": [
{
"name": "Mary Brown",
"comment": "Lies, lies, lies",
"age": 42,
"stars": 1,
"date": "2014-10-18"
},
{
"name": "John Smith",
"comment": "You're making it up!",
"age": 28,
"stars": 2,
"date": "2014-10-16"
}
]
}
嵌套查询
GET /_search
{
"query": {
"nested": {
"path": "comments",
"filter": {
"range": {
"comments.date": {
"gte": "2014-10-01",
"lt": "2014-11-01"
}
}
}
}
},
"sort": {
"comments.stars": {
"order": "asc",
"mode": "min",
"nested_filter": {
"range": {
"comments.date": {
"gte": "2014-10-01",
"lt": "2014-11-01"
}
}
}
}
}
}
上面的方案在ES6.1之后是不行的,因为嵌套类型的排序有特殊的排序nested sort选项,开启的方式和netsed查询很像。所以我们升级了一下
POST /_search
{
"query" : {
"term" : { "product" : "chocolate" }
},
"sort" : [
{
"offer.price" : {
"mode" : "avg",
"order" : "asc",
"nested": {
"path": "offer",
"filter": {
"term" : { "offer.color" : "blue" }
}
}
}
}
]
}
java代码的写法
BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("custom_info.deptUpdateTime");
rangeQueryBuilder.gte(condition.getDeptUpdateTime().getStartTime() + "T00:00:00");
rangeQueryBuilder.lte(condition.getDeptUpdateTime().getEndTime() + "T23:59:59");
boolBuilder.must(rangeQueryBuilder);
QueryBuilder nestedQueryBuilder = new NestedQueryBuilder(
"custom_info",
boolBuilder,
ScoreMode.None
);
本文深入探讨了Elasticsearch中的ESNested嵌套类型,解释了其与普通object类型的区别,以及如何利用nested类型进行高效的数据存储和查询。文章还介绍了nested类型的优缺点,包括读取性能高但更新成本增加的特点,并提供了nested查询和排序的具体示例。
1750

被折叠的 条评论
为什么被折叠?



