使用 Elasticsearch nested 可能会遇到的疑问

什么是nested类型

在理解nested类型之前, 我们还需要理解object类型, 所以你需要看查看以下两个官方文档:

  • Object datatype
  • Nested datatype

简单的说, Elasticsearch中的文档支持存储嵌套的json结构, 如

{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

如果我们将以上json插入到文档中, user字段会被dynamic mapping为object类型

现在 user下的first字段也能被索引到, 但object类型有一个特性是会将数据拍扁为以下结构:

{
  "group" :        "fans",
  "user.first" : [ "alice", "john" ],
  "user.last" :  [ "smith", "white" ]
}

可以看到, first和last(也就是alice和white)没有了关联关系, 在query的时候就会返回错误结果.

现在就需要nested上场了, 如果user是nested类型, 那么数据将会被独立为多个独立文档以保障嵌套字段间的关系.

{
  "user.first" : "alice",
  "user.last" :  "white"
}
{
  "user.first" : "john",
  "user.last" :  "smith"
}

使用nested

上面也说到, 如果使用默认的dynamic mapping, json对象会被匹配为object类型, 如果要使用nested你就需要再创建Index的时候指定mapping

  • indices-create
  • mapping

值得注意的是在查询嵌套结构的时候也和普通的query不同, 需要使用到nested-query

例如一个文档的mapping是这样的:

{
    "mappings": {
        "type1" : {
            "properties" : {
                "obj1" : {
                    "type" : "nested"
                }
            }
        }
    }
}

就需要这样写query语句

{
    "query": {
        "nested" : {
            "path" : "obj1",
            "query" : {
                "bool" : {
                    "must" : [
                        { "match" : {"obj1.name" : "blue"} },
                        { "range" : {"obj1.count" : {"gt" : 5}} }
                    ]
                }
            }
        }
    }
}

Dynamic templates

当动态添加字段的时候Elasticsearch会自动推断类型, 如string就会使用text类型存储.

但如果你需要修改这个逻辑就需要使用到dynamic templates.

比如在上面的例子中, 我们需要对动态添加的user.first字段进行精确搜索, 而不是全文搜索, 就需要使用到keyword类型. 为了达到这个目的, 我们可以这样写dynamic_templates

PUT my_index
{
  "mappings": {
    "my_type": {
      "dynamic_templates": [
        {
          "strings_as_keywords": {
            "match_mapping_type": "string",
            "mapping": {
              "type": "keyword"
            }
          }
        }
      ]
    }
  }
}

当然这个用法只是dynamic_template的冰山一角, 更多用法请参考官方文档 - Dynamic templates

text 与 keyword 类型

text datatype是我们最常用的类型, 可以用来实现全文搜索, 原理是在入库的时候text类型的字段会被analyzer(分析器)分割成多个terms再被索引, 这也是实现Inverted index(倒排索引)步骤之一.

keyword datatype和text不同的时候, keyword不会被分析, 所有的内容都将被存储为一个term. 它通常被用于 过滤, 排序, 聚合, 而不是搜索.

你可以在文档 - term-qury中找到Why doesn’t the term query match my document?段来理解什么是analyzer, keyword, text.

你可能感兴趣的:(使用 Elasticsearch nested 可能会遇到的疑问)