(一)ES如何存储对象
ElasticSearch中可以将数据以对象的方式存储并查询,但是ES底层的Lucene 没有内部对象的概念,因此如果通过默认的方式往ES中插入对象,ES会将对象层次结构扁平化为字段名称和值的简单列表。 比如下面这一段数据:
PUT my_index/_doc/1
{
"group" : "fans",
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
复制代码
ES内部会将这份数据变成下面这个样子:
{
"group" : "fans",
"user.first" : [ "alice", "john" ],
"user.last" : [ "smith", "white" ]
}
复制代码
缺失了first和last之间的关联性。比如这个时候想查询一个first为John,last为White的人,理论上是没有这个人的,但是实际上名为fans的这个组还是被查出来了。
GET my_index/_search
{
"query": {
"bool": {
"must": [
{ "match": { "user.first": "John" }},
{ "match": { "user.last": "White" }}
]
}
}
}
复制代码
从结果可以看到,两条数据都被查询出来了。
(二)Nested类型
这个时候就需要用到nested,nested类型是object数据类型的特殊版本,它允许对象数组以一种可以相互独立查询的方式进行索引。
在Nested内部,每个对象索引其实是一个单独