ES宽表查询常见问题

ES宽表查询常见问题,本帖指的是想关联的子文档集合,以属性的形式嵌套在我们的父文档中:
直接创建索引

PUT my-index-000001

插入文档

PUT my-index-000001/_doc/1
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

执行布尔查询:

GET my-index-000001/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "user.first": "Alice" }},
        { "match": { "user.last":  "Smith" }}
      ]
    }
  }
}

很明显不应该命中,然而
ES宽表查询常见问题_第1张图片
出现这种原因是因为user默认是普通对象,在没有声明的情况下,会变成平铺式,所以就绕过了这个查询的联合match

怎么避免呢,可以使用es的特性指定对象是nested。

# 测试多表
DELETE my-index-000001
# 重建索引
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested" 
      }
    }
  }
}
#插入数据
PUT my-index-000001/_doc/1
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

测试使用原来的语句终于不会被绕过去了,但是修改成user.last改成"White"也不行,其实是其有自己特定的语法:

GET my-index-000001/_search
{
  "query": {
    "bool": {
      "must": [
         {
            "nested": {
              "path": "user",
              "query": {
                "bool": {
                  "must": [
                    { "match": { "user.first":  "Alice" }},
                    {"match": {"user.last": "White"}}
                  ]
                }
              }
            }
         }
      ]
    }
  }
}

结果:ES宽表查询常见问题_第2张图片
而last使用Smith是不行,修复问题了

#使用nested
GET my-index-000001/_search
{
  "query": {
    "bool": {
      "must": [
         {
            "nested": {
              "path": "user",
              "query": {
                "bool": {
                  "must": [
                    { "match": { "user.first":  "Alice" }},
                    {"match": {"user.last": "Smith"}}
                  ]
                }
              }
            }
         }
      ]
    }
  }
}

ES宽表查询常见问题_第3张图片

你可能感兴趣的:(搜索引擎,elasticsearch,大数据,big,data)