ElasticSearch-对象类型和嵌套(nested)对象

一、对象类型

使用json、json数组作为字段值,动态映射会默认使用对象类型(type object)

1.1字段值为json对象

POST users/users/1
{
    "name":"王月",
    "description":{
        "date":"2015-12-22",
        "title":"go to School"
    }
}

相当于插入一条: 

{
    "name":"王月",
    "description.date":"2015-12-22",
    "description.title":"go to School"
}

1.2字段值为json数组

POST users/users/1
{
    "name":"王月",
    "user_id":1,
    "description":[
        {
            "date":"2015-12-22",
            "title":"go to School"
        },
        {
            "date":"2016-10-22",
            "title":"go Shopping"
        }
    ]
}

相当于插入一条:

{
    "name":"王月",
    "user_id":1,
    "description.date":["2015-12-22","2016-10-22"],
    "description.title":["go to School","go Shopping"]
}

但是当我们搜索:“2015年” 且“包含shopping”的记录时,这条记录仍然可以被搜索出来。就是因为存储对象数组时使用object会丢失层级关系,解决方式就是需要Nested格式解决。

{
    "query":{
        "bool":{
            "must":[
                {
                    "term":{
                        "description.title":{
                            "value":"school"
                        }
                    }
                },
                {
                    "range":{
                        "description.date":{
                            "from":"2015-01-01",
                            "to":"2015-12-31"
                        }
                    }
                }
            ]
        }
    }
}

查看此时的mapping结构:(其实是description字段里面增加了两个key).

二、Nested

创建索引mapping:设置type为nested。然后再写入刚刚的数据,再查询“2015年” 且“包含shopping”的记录,无结果返回,正确。

{
    "mappings":{
        "users":{
            "properties":{
                "description":{
                    "type":"nested",
                    "properties":{
                        "date":{
                            "type":"date"
                        },
                        "title":{
                            "type":"text",
                            "fields":{
                                "keyword":{
                                    "type":"keyword",
                                    "ignore_above":256
                                }
                            }
                        }
                    }
                },
                "name":{
                    "type":"text",
                    "fields":{
                        "keyword":{
                            "type":"keyword",
                            "ignore_above":256
                        }
                    }
                }
            }
        }
    }
}

这时候当你再执行插入语句时:相当于插入了三条记录,一条根文档和两条嵌套文档。

{
    "name":"王月"
}
{
    "description.date":"2015-12-22",
    "description.title":"go to School"
}
{
    "description.date":"2016-10-22",
    "description.title":"go Shopping"
}

需要说明的一点,为了保证性能,一个文档和其嵌套文档都集中在同一个Segment中。而父子关系的文档因为是子文档和父文档相互独立查询起来更耗时,但是对于更新更加友好。子文档和父文档的更新相互不影响。

发布了18 篇原创文章 · 获赞 7 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章