elasticsearch的object类型和动态映射

来源:互联网 发布:叮叮软件 编辑:程序博客网 时间:2024/05/18 01:15

我们需要讨论的最后一个自然JSON数据类型是对象(object)——在其它语言中叫做hash、hashmap、dictionary 或者 associative array.

内部对象(inner objects)经常用于在另一个对象中嵌入一个实体或对象。例如,做为在tweet文档中user_nameuser_id的替代,我们可以这样写:

{    "tweet":            "Elasticsearch is very flexible",    "user": {        "id":           "@johnsmith",        "gender":       "male",        "age":          26,        "name": {            "full":     "John Smith",            "first":    "John",            "last":     "Smith"        }    }}

内部对象的映射

Elasticsearch 会动态的检测新对象的字段,并且映射它们为 object 类型,将每个字段加到 properties字段下

{  "gb": {    "tweet": { <1>      "properties": {        "tweet":            { "type": "string" },        "user": { <2>          "type":             "object",          "properties": {            "id":           { "type": "string" },            "gender":       { "type": "string" },            "age":          { "type": "long"   },            "name":   { <3>              "type":         "object",              "properties": {                "full":     { "type": "string" },                "first":    { "type": "string" },                "last":     { "type": "string" }              }            }          }        }      }    }  }}

<1> 根对象.

<2><3> 内部对象.

username字段的映射与tweet类型自己很相似。事实上,type映射只是object映射的一种特殊类型,我们将 object 称为根对象。它与其他对象一模一样,除非它有一些特殊的顶层字段,比如 _source,_all 等等。

内部对象是怎样被索引的

Lucene 并不了解内部对象。 一个 Lucene 文件包含一个键-值对应的扁平表单。 为了让 Elasticsearch 可以有效的索引内部对象,将文件转换为以下格式:

{    "tweet":            [elasticsearch, flexible, very],    "user.id":          [@johnsmith],    "user.gender":      [male],    "user.age":         [26],    "user.name.full":   [john, smith],    "user.name.first":  [john],    "user.name.last":   [smith]}

内部栏位可被归类至name,例如"first"。 为了区别两个拥有相同名字的栏位,我们可以使用完整路径,例如"user.name.first" 或甚至类型名称加上路径:"tweet.user.name.first"

注意: 在以上扁平化文件中,并没有栏位叫作user也没有栏位叫作user.name。 Lucene 只索引阶层或简单的值,而不会索引复杂的资料结构。

动态映射

当 Elasticsearch 处理一个位置的字段时,它通过【动态映射】来确定字段的数据类型且自动将该字段加到类型映射中。

有时这是理想的行为,有时却不是。或许你不知道今后会有哪些字段加到文档中,但是你希望它们能自动被索引。或许你仅仅想忽略它们。特别是当你使用 Elasticsearch 作为主数据源时,你希望未知字段能抛出一个异常来警示你。

幸运的是,你可以通过 dynamic 设置来控制这些行为,它接受下面几个选项:

true:自动添加字段(默认)

false:忽略字段

strict:当遇到未知字段时抛出异常

dynamic 设置可以用在根对象或任何 object 对象上。你可以将 dynamic 默认设置为 strict,而在特定内部对象上启用它:

PUT /my_index{    "mappings": {        "my_type": {            "dynamic":      "strict", <1>            "properties": {                "title":  { "type": "string"},                "stash":  {                    "type":     "object",                    "dynamic":  true <2>                }            }        }    }}

<1> 当遇到未知字段时,my_type 对象将会抛出异常

<2> stash 对象会自动创建字段

通过这个映射,你可以添加一个新的可搜索字段到 stash 对象中:

PUT /my_index/my_type/1{    "title":   "This doc adds a new field",    "stash": { "new_field": "Success!" }}

但是在顶层做同样的操作则会失败:

PUT /my_index/my_type/1{    "title":     "This throws a StrictDynamicMappingException",    "new_field": "Fail!"}

备注:将 dynamic 设置成 false 完全不会修改 _source 字段的内容。_source 将仍旧保持你索引时的完整 JSON 文档。然而,没有被添加到映射的未知字段将不可被搜索。


+
原创粉丝点击