1、默认情况下ES会把JSON对象直接映射为object类型,只有手动设置才会映射为nested类型
2、object类型可以直接使用普通的逗号(.)查询,比如"term": {"inspector.id": {"value": "1222"}}
3、nested类型的查询需要使用nested查询:"nested": {"path": "inspector","query": {"exists": {"field": "inspector.id"}}}
4、两种查询方式不兼容,如果大家想做改动的话,需要对java程序进行修改,风险比较大。
5、注意object类型的数组,查询的时候,结果可能是你不想要的值
- {
- "tweet": "Elasticsearch is very flexible",
- "user": {
- "id": "@johnsmith",
- "gender": "male",
- "age": 26,
- "name": {
- "full": "John Smith",
- "first": "John",
- "last": "Smith"
- }
- }
- }
Elasticsearch 会动态监测新的对象域并映射它们为 object类型,在 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" }
- }
- }
- }
- }
- }
- }
- }
- }
从上面的映射我们可以看到user 和 name 字段都被映射为"type":"object"
Lucene 不理解内部对象。 Lucene 文档是由一组键值对列表组成的。为了能让 Elasticsearch 有效地索引对象,对其进行了扁平化处理,它把我们的文档转化成这样:
- {
- "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]
- }
使用全路径进行查询 (例如, user.name.first )
假设我们有个 followers 数组:
- {
- "followers": [
- { "age": 35, "name": "Mary White"},
- { "age": 26, "name": "Alex Jones"},
- { "age": 19, "name": "Lisa Smith"}
- ]
- }
这个文档会像我们之前描述的那样被扁平化处理,结果如下所示:
- {
- "followers.age": [19, 26, 35],
- "followers.name": [alex, jones, lisa, smith, mary, white]
- }
{age: 35} 和 {name: Mary White} 之间的相关性已经丢失了,因为每个多值域只是一包无序的值,而不是有序数组。于是我们不能得到一个准确的答案:“是否有一个26岁 名字叫 Alex Jones 的追随者?” 嵌套对象 就是来解决这个问题的。
- PUT /my_index/blogpost/1
- {
- "title": "Nest eggs",
- "body": "Making your money work...",
- "tags": [ "cash", "shares" ],
- "comments": [
- {
- "name": "John Smith",
- "comment": "Great article",
- "age": 28,
- "stars": 4,
- "date": "2014-09-01"
- },
- {
- "name": "Alice White",
- "comment": "More like this please",
- "age": 31,
- "stars": 5,
- "date": "2014-10-22"
- }
- ]
- }
2、映射为nested类型并索引:
将 comments 字段类型设置为 nested 而不是 object 后,每一个嵌套对象都会被索引为一个 隐藏的独立文档 ,举例如下:
- {
- "comments.name": [ john, smith ],
- "comments.comment": [ article, great ],
- "comments.age": [ 28 ],
- "comments.stars": [ 4 ],
- "comments.date": [ 2014-09-01 ]
- }
- {
- "comments.name": [ alice, white ],
- "comments.comment": [ like, more, please, this ],
- "comments.age": [ 31 ],
- "comments.stars": [ 5 ],
- "comments.date": [ 2014-10-22 ]
- }
- {
- "title": [ eggs, nest ],
- "body": [ making, money, work, your ],
- "tags": [ cash, shares ]
- }
在独立索引每一个嵌套对象后,对象中每个字段的相关性得以保留。我们查询时,也仅仅返回那些真正符合条件的文档。
3.1、由于嵌套文档直接存储在文档内部,查询时嵌套文档和根文档联合成本很低,速度和单独存储几乎一样。
3.2、嵌套文档是隐藏存储的,我们不能直接获取。如果要增删改一个嵌套对象,我们必须把整个文档重新索引才可以。
3.3、查询的时候返回的是整个文档,而不是嵌套文档本身
由于嵌套对象 被索引在独立隐藏的文档中,我们无法直接查询它们。 相应地,我们必须使用 nested 查询 去获取它们:
- GET /my_index/blogpost/_search
- {
- "query": {
- "bool": {
- "must": [
- {
- "match": {
- "title": "eggs"
- }
- },
- {
- "nested": {
- "path": "comments",
- "query": {
- "bool": {
- "must": [
- {
- "match": {
- "comments.name": "john"
- }
- },
- {
- "match": {
- "comments.age": 28
- }
- }
- ]
- }
- }
- }
- }
- ]
- }}}