使用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).
创建索引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中。而父子关系的文档因为是子文档和父文档相互独立查询起来更耗时,但是对于更新更加友好。子文档和父文档的更新相互不影响。