我们想让tag字段包含多个字段,这非常有可能发生。我们可以索引一个标签数组来代替单一字符串:

对于数组不需要特殊的映射。任何一个字段可以包含零个、一个或多个值,同样对于全文字段将被分析并产生多个词。

言外之意,这意味着数组中所有值必须为同一类型。你不能把日期和字符窜混合。如果你创建一个新字段,这个字段索引了一个数组,Elasticsearch将使用第一个值的类型来确定这个新字段的类型。

空字段

当然数组可以是空的。这等价于有零个值。事实上,Lucene没法存放null值,所以一个null值的字段被认为是空字段。

  1. "empty_string": "",
  2. "null_value": null,
  3. "empty_array": [],
  4. "array_with_null_value": [ null ]

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

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

内部对象的映射

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

  1. {
  2. "gb": {
  3. "tweet": { <1>
  4. "tweet": { "type": "string" },
  5. "user": { <2>
  6. "properties": {
  7. "id": { "type": "string" },
  8. "gender": { "type": "string" },
  9. "age": { "type": "long" },
  10. "name": { <3>
  11. "type": "object",
  12. "properties": {
  13. "full": { "type": "string" },
  14. "first": { "type": "string" },
  15. "last": { "type": "string" }
  16. }
  17. }
  18. }
  19. }
  20. }
  21. }
  22. }

<1> 根对象.

<2><3> 内部对象.

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

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

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

对象-数组

内部对象数组

最后,一个包含内部对象的数组如何索引。 我们有个数组如下所示:

  1. {
  2. "followers": [
  3. { "age": 35, "name": "Mary White"},
  4. { "age": 26, "name": "Alex Jones"},
  5. { "age": 19, "name": "Lisa Smith"}
  6. ]
  7. }

此文件会如我们以上所说的被扁平化,但其结果会像如此:

{name: Mary White}之间的关联会消失,因每个多值的栏位会变成一个值集合,而非有序的阵列。 这让我们可以知道:

  • 是否有26岁的追随者?

但我们无法取得准确的资料如: