elasticsearch进阶(2)—— nested/flattened/join 数据类型

一、参考

elasticsearch 学习系列目录——更新ing

Nested field type

flattened field type

Elasticsearch:flattened 数据类型 (7.3 发行版新功能)

join field type

Elasticsearch Nested类型深入详解

Elasticsearch - The Trouble with Nested Documents

二、nested

2.1 字段值为列表

当不使用nested字段类型时候,对于某个字段,其值是一个列表

elasticsearch进阶(2)—— nested/flattened/join 数据类型_第1张图片

如上图,用户张三李四的信息混合到一起,此时查找张四,同样可以获取

PUT yztest/_doc/1
{
  "group": "fans",
  "user": [
    {
      "first": "张",
      "last": "三"
    },
    {
      "first": "李",
      "last": "四"
    }
  ]
}

GET yztest/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "user.first.keyword": "张"
          }
        },
        {
          "term": {
            "user.last.keyword": "四"
          }
        }
      ]
    }
  }
}

2.2 设置nested类型

elasticsearch进阶(2)—— nested/flattened/join 数据类型_第2张图片

如上图,设置user字段类型为 nested, 在lucene内部,会存储为3个文档,其中nested类型的每个元素都作为一个独立的文档存在

注意:查询nested字段需要使用nested查询语法

DELETE yztest

PUT yztest/
{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested"
      }
    }
  }
}

PUT yztest/_doc/1
{
  "group": "fans",
  "user": [
    {
      "first": "张",
      "last": "三"
    },
    {
      "first": "李",
      "last": "四"
    }
  ]
}

GET yztest/_search
{
  "query": {
    "nested": {
      "path": "user",
      "query": {
        "bool": {
          "filter": [
            {
              "term": {
                "user.first.keyword": "张"
              }
            },
            {
              "term": {
                "user.last.keyword": "三"
              }
            }
          ]
        }
      }
    }
  }
}

2.3 使用场景

子文档(例如:上面的user), 较少更新,查询频繁的场景

2.4 限制条件

elasticsearch进阶(2)—— nested/flattened/join 数据类型_第3张图片

三、join

3.1 定义join字段

类似于MySQL中的join关联功能,ES中有对应的一个join类型,可以通过join类型,定义父子关联关系

DELETE yztest

PUT yztest/
{
  "mappings": {
    "properties": {
      "my_id": {
        "type": "keyword"
      },
      "my_join_field": {
        "type": "join",
        "relations": {
          "question": "answer"
        }
      }
    }
  }
}

3.2 使用场景

如果数据包含着一对多关系,并且关联关系的子字段可能取值明显多于父子段(例如:一个1对多关系为商品和商品定价,同一个商品可能定价有多种可能,此时可以使用join类型定义)

3.3 使用限制

elasticsearch进阶(2)—— nested/flattened/join 数据类型_第4张图片

3.4 查询

# 基于子文档查询父文档
GET yztest/_search
{
  "query": {
    "has_child": {
      "type": "answer",
      "query": {
        "match": {
          "text": "is answer"
        }
      }
    }
  }
}

# 基于父文档查询子文档
GET yztest/_search
{
  "query": {
    "has_parent": {
      "parent_type": "question",
      "query": {
        "match": {
          "text": "is question"
        }
      }
    }
  }
}
# 聚合查询, my_join_filed#question 新字段 表示 question的_id
GET yztest/_search
{
  "size": 0,
  "aggs": {
    "a1": {
      "terms": {
        "field": "my_join_field#question",
        "size": 10
      }
    }
  }
}

四、flattened

4.1 产生背景

默认情况下,一个对象类型字段,其中的所有子字段都会分别进行索引与映射(扁平化),这样可能会导致 映射爆炸,

ES通过 flattened 类型,提供了一种折衷的解决方法,

(1) flattened类型会将整个对象,映射为一整个字段
(2) 但是, flattened类型,只提供了部分的查询功能

4.2 定义与使用

DELETE yztest

PUT yztest/
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text"
      },
      "labels": {
        "type": "flattened"
      }
    }
  }
}
# 数据写入
POST yztest/_doc/1
{
  "title": "Results are not sorted correctly.",
  "labels": {
    "priority": "urgent",
    "release": ["v1.2.5", "v1.3.0"],
    "timestamp": {
      "created": 1541458026,
      "closed": 1541457010
    }
  }
}

POST yztest/_doc/2
{
  "title": "Results are not sorted correctly.",
  "labels": {
    "other": "this is a test label"
  }
}
# term查询
GET yztest/_search
{
  "query": {
    "term": {
      "labels.release": {
        "value": "v1.2.5"
      }
    }
  }
}

# queryString 查询,通配
GET yztest/_search
{
  "profile": true, 
  "query": {
    "query_string": {
      "default_field": "labels.other",
      "query": "*this*"
    }
  }
}

4.3 查询限制

elasticsearch进阶(2)—— nested/flattened/join 数据类型_第5张图片

elasticsearch进阶(2)—— nested/flattened/join 数据类型_第6张图片

你可能感兴趣的:(elasticsearch)