一、题目
存在索引phones,其中存在两条数据如下
PUT phones/_doc/1
{
"brand": "Samsumg",
"model": "Galaxy S9+",
"features": [
{
"type": "os",
"value": "Android"
},
{
"type": "storage",
"value": "64"
},
{
"type": "camera_resolution",
"value": "12"
}
]
}PUT phones/_doc/2
{
"brand": "Apple",
"model": "iPhone XR",
"features": [
{
"type": "os",
"value": "Apple 10s"
},
{
"type": "storage",
"value": "128"
},
{
"type": "camera_resolution",
"value": "12"
}
]
}写入数据后使用如下查询语句查询,但是不符合预期,在索引中其实并不存在storage为12的数据
GET /phones/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"features.type": "storage"
}
},
{
"match": {
"features.value": "12"
}
}
]
}
}
}重新定义个索引phones_new 写入数据,保持原features下type和value结构,预期使用查询语句预期无数据可以满足。
二、思考
Elasticsearch 没有内部对象的概念。因此,它将对象层次结构扁平化为一个简单的字段名和值列表。引用官网示例解释例如下截图
如果想将通过嵌套对象方式存储,可以通过将数据设置为nested类型,它是object一种数据类型,允许对象数组以相互独立的方式进行索引。
三、解题
Step 1、使用nesed创建新mapping
PUT phones_new
{
"settings": {
"number_of_replicas": 1,
"number_of_shards": 1
},
"mappings": {
"properties": {
"brand": {
"type": "text"
},
"model": {
"type": "text"
},
"features": {
"type": "nested",
"properties": {
"fields": {
"type": "keyword"
},
"value": {
"type": "text"
}
}
}
}
}
}
Step 2、修改原查询为nested
POST phones_new/_search
{
"query": {
"nested": {
"path": "features",
"query": {
"bool": {
"must": [
{
"match": {
"features.type": "storage"
}
},
{
"match": {
"features.value": 12
}
}
]
}
}
}
}
}
四、总结
1、Elasticsearch 没有内部对象的概念。因此,它将对象层次结构扁平化为一个简单的字段名和值列表。可以通过设置为nested类型,是object一种数据类型,允许对象数组以相互独立的方式进行索引。
2、嵌套文档是指对于一行数据(文档)可以包含多个子行(子文档),多个子行保存在一个嵌套类型字段中。
3、嵌套类型的查询与query存在区别需要指定path。此外嵌套类型的查询性能相比其他类型的查询性能更低一些。
4、nested类型的对象默认不能超过50个,可通过index.mapping.nested_fields.limit
修改。
5、一个文档中,nested类型中包含的嵌套对象的数量默认不能超过10000个,可通过index.mapping.nested_objects.limit
修改。
参考资料
- Nested query | Elasticsearch Guide [8.1] | Elastic
- Nested field type | Elasticsearch Guide [8.1] | Elastic
送一波福利:
标签:features,--,phones,value,Nested,嵌套,ElasticSearch,nested,type From: https://blog.csdn.net/hengzhepa/article/details/141817012