除了前面已经提到的简单的数据类型,JSON也有null,array和object类型,这些都是被ES支持的。
Multi-value fields
我们想让我们的tag field的值多于一个而不是一个字符串,这个也是可能的,我们能把一个数组存储到tags:
{"tag":["search","nosql"]}
对数组来说,不许要特别的mapping。任何的field都可以包含若干个value,就像full text字段一样会被分词器拆分成多个terms。
这里也暗示了数组中所有的value的数据类型必须都要是一致的。你当然可以在string中混合使用了多种数据类型,但是在你存储一个数组的时候,ES会使用数组中的第一个元素的类型作为所有数组元素的类型。数组中的元素是无序的,你不能引用第一个元素或者是最后一个元素。你就当ES中的数组是对若干的value的一个打包就行了。
Empty fields
ES的field能存储array,当然array也可能是空值,这个就像当于存储了0个value。事实上,在Lucene中没有存储null的方式,因此一个field的值是null这个field就会当做empty
fields。这些empty field是不会被存储的,有一下四种形式的empty field:
"empty_string": "",
"null_value": null,
"empty_array": [],
"array_with_null_value": [null]
multi-level objects
我们将要讨论的最后一个原生的JSON数据类型就是object——就像在其他语言中广为人知的hash,hashmap,dictionary或者是关联array。内部的object常常用来嵌套一个实体类,或者其他的嵌套的object。例如,我们不把user_name,user_id放到tweet的document,我们能这样写:
{
"tweet": "Elasticsearch is very flexible",
"user":{
"id": "@johnsmith",
"gender": "male",
"age": 26,
"name":{
"full": "John Smith",
"first": "John",
"last": "Smith"
}
}
}
mapping for inner objects
ES能动态的检测新的object field并且对object进行映射,每个object的field都在properties属性下:
{
"gb":{
"tweet":{
"properties":{
"tweet": {"type":"string"},
"user":{
"type": "object",
"properties":{
"id": {"type":"string"},
"gender": {"type":"string"},
"age": {"type":"long" },
"name": {
"type": "object",
"properties":{
"full": {"type":"string"},
"first": {"type":"string"},
"last": {"type":"string"}
}
}
}
}
}
}
}
}
标记1表示的是根对象
标记2和3表示的是内部对象
how inner objects are indexed
Lucene是不是别内部对象的。一个Lucene的document识别的是key-value平行列表。为了ES能够存储object,他对document做了如下的转换:
{
"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]
}
内部field都可以通过名称进行引用,为了区分两个内部object的相同的字段名,我们可以通过全路径进行引用,例如:"user.name.first"或者“tweet.user.name.first"。
在上面的扁平的document中,没有字段的名称是user也没有字段的名称是user.name。Lucene只是存储了简单的值,而不能存储复杂的数据结构。
arrays of inner objects
最后,看看内部object中的array是怎么存储的,假设我们有下名这个名为followers的数组:
{
"followers":[
{"age":35,"name":"Mary White"},
{"age":26,"name":"Alex Jones"},
{"age":19,"name":"Lisa Smith"}
]
}
这个document就会如下的扁平的存储:
{
"followers.age": [19,26,35],
"followers.name": [alex, jones, lisa, smith, mary, white]
}
{age:
和
35}{name: Mary
White}的关系已经丢失了,因为每个multi-value字段是对values的打包,并且是无序的。我们可以这样问:
- Is there a follower who is 26
years old?
但是如果我们想下面这样问就得不到一个精确的答案:
- Is there a follower who is 26
years old and who is called Alex
Jones?
内部object的关系, which are able to answer queries like
these,被内部类调用,我们稍后将会在 Related
Documents (TODO)中进行讨论。
原文:http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/complex-core-fields.html
复杂的核心字段类型(Complex core field types),布布扣,bubuko.com