一步一步理解Elasticsearch中的object,nested,join数据类型

2024-08-05 15:13:20 浏览数 (2)

为了更好的理解三种数据类型之间不同,尽量使用相的数据,相同的mapping, 只是数据类型不一样。

一、object类型

代码语言:json复制
DELETE orders_object
PUT /orders_object
{
  "mappings": {
    "properties": {
      "order_id": { "type": "keyword" },
      "customer": { "type": "text" },
      "items": {
        "type": "object",
        "properties": {
          "product_id": { "type": "keyword" },
          "quantity": { "type": "integer" }
        }
      }
    }
  }
}

PUT /orders_object/_doc/1
{
  "order_id": "1",
  "customer": "John Doe",
  "items": [
    { "product_id": "A", "quantity": 2 },
    { "product_id": "B", "quantity": 1 }
  ]
}

PUT /orders_object/_doc/2
{
  "order_id": "2",
  "customer": "Jane Smith",
  "items": [
    { "product_id": "A", "quantity": 1 },
    { "product_id": "C", "quantity": 3 }
  ]
}

想查询product_id=A ,并且quantity>=2的数据查询出来。

代码语言:json复制
GET /orders_object/_search?filter_path=**.hits
{
  "query": {
    "bool": {
      "must": [
        {
          "match": { "items.product_id": "A"}
        },
        {
          "range": {  "items.quantity": {  "gte": 2 }  }
        }
      ]
    }
  }
}

结果显示两条记录都会被查出来:order_id=1,order_id=2

代码语言:txt复制
{
  "hits": {
    "hits": [
      {
        "_index": "orders_object",
        "_id": "1",
        "_score": 1.2292043,
        "_source": {
          "order_id": "1",
          "customer": "John Doe",
          "items": [
            {
              "product_id": "A",
              "quantity": 2
            },
            {
              "product_id": "B",
              "quantity": 1
            }
          ]
        }
      },
      {
        "_index": "orders_object",
        "_id": "2",
        "_score": 1.2292043,
        "_source": {
          "order_id": "2",
          "customer": "Jane Smith",
          "items": [
            {
              "product_id": "A",
              "quantity": 1
            },
            {
              "product_id": "C",
              "quantity": 3
            }
          ]
        }
      }
    ]
  }
}

二、nested类型

代码语言:json复制
DELETE orders_nested

PUT /orders_nested
{
  "mappings": {
    "properties": {
      "order_id": { "type": "keyword" },
      "customer": { "type": "text" },
      "items": {
        "type": "nested",
        "properties": {
          "product_id": { "type": "keyword" },
          "quantity": { "type": "integer" }
        }
      }
    }
  }
}

PUT /orders_nested/_doc/1
{
  "order_id": "1",
  "customer": "John Doe",
  "items": [
    { "product_id": "A", "quantity": 2 },
    { "product_id": "B", "quantity": 1 }
  ]
}

PUT /orders_nested/_doc/2
{
  "order_id": "2",
  "customer": "Jane Smith",
  "items": [
    { "product_id": "A", "quantity": 1 },
    { "product_id": "C", "quantity": 3 }
  ]
}


GET /orders_nested/_search
{
  "query": {
    "nested": {
      "path": "items",
      "query": {
        "bool": {
          "must": [
            { "match": { "items.product_id": "A" } },
            { "range": { "items.quantity": { "gte": 2 } } }
          ]
        }
      }
    }
  }
}

显示结果如下:

代码语言:txt复制
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1.6931472,
    "hits": [
      {
        "_index": "orders_nested",
        "_id": "1",
        "_score": 1.6931472,
        "_source": {
          "order_id": "1",
          "customer": "John Doe",
          "items": [
            {
              "product_id": "A",
              "quantity": 2
            },
            {
              "product_id": "B",
              "quantity": 1
            }
          ]
        }
      }
    ]
  }
}

这不同的结果,充分体现了object类型和nested类型之间的区别

三、join数据类型

代码语言:json复制
#3. join 类型
DELETE orders_join
PUT /orders_join
{
  "mappings": {
    "properties": {
      "order_id": { "type": "keyword" },
      "customer": { "type": "text" },
      "items": {
        "type": "join",
        "relations": {
          "order": "item"
        }
      },
      "product_id": { "type": "keyword" },
      "quantity": { "type": "integer" }
    }
  }
}

#添加父文档
PUT /orders_join/_doc/1
{
  "order_id": "1",
  "customer": "John Doe",
  "items": {
    "name": "order"
  }
}

#添加子文档
PUT /orders_join/_doc/2?routing=1
{
  "product_id": "A",
  "quantity": 2,
  "items": {
    "name": "item",
    "parent": "1"
  }
}

PUT /orders_join/_doc/3?routing=1
{
  "product_id": "B",
  "quantity": 1,
  "items": {
    "name": "item",
    "parent": "1"
  }
}

PUT /orders_join/_doc/4?routing=2
{
  "product_id": "A",
  "quantity": 1,
  "items": {
    "name": "item",
    "parent": "2"
  }
}

PUT /orders_join/_doc/5?routing=2
{
  "product_id": "C",
  "quantity": 3,
  "items": {
    "name": "item",
    "parent": "2"
  }
}


GET /orders_join/_search
{
  "query": {
    "has_child": {
      "type": "item",
      "query": {
        "match": { "product_id": "A" }
      }
    }
  }
}

GET /orders_join/_search
{
  "query": {
    "has_child": {
      "type": "item",
      "query": {
        "bool": {
          "must": [
            { "match": { "product_id": "A" } },
            { "range": { "quantity": { "gte": 2 } } }
          ]
        }
      }
    }
  }
}


GET /orders_join/_search
{
  "query": {
    "has_parent": {
      "parent_type": "order",
      "query": {
        "match": { "customer": "John Doe" }
      }
    }
  }
}

总结

  • object 类型: 适用于简单的嵌套结构,数据被展平存储,不支持复杂的嵌套查询。
  • nested 类型: 适用于需要复杂查询的嵌套结构,支持对嵌套对象的精确查询和过滤。
  • join 类型: 适用于处理父子关系的场景,支持在父文档和子文档之间进行复杂的查询和关联。

根据具体的业务需求选择合适的数据类型,以优化查询性能和数据建模的复杂性。

0 人点赞