ElasticSearch 备考 -- Nested

ElasticSearch 备考 -- Nested_第1张图片

一、题目

存在索引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 没有内部对象的概念。因此,它将对象层次结构扁平化为一个简单的字段名和值列表。引用官网示例解释例如下截图

ElasticSearch 备考 -- Nested_第2张图片

如果想将通过嵌套对象方式存储,可以通过将数据设置为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

送一波福利:

ElasticSearch 备考 -- Nested_第3张图片

你可能感兴趣的:(ES,备考,elasticsearch,大数据,搜索引擎,学习,es)