Bool并在ElasticSearch中搜索属性

时间:2015-08-10 15:14:58

标签: elasticsearch

我在ES中有一个非常小的文档数据集:

    {"id":1, "name": "John", "team":{"code":"red", "position":"P"}}

    {"id":2, "name": "Jack", "team":{"code":"red", "position":"S"}}

    {"id":3, "name": "Emily", "team":{"code":"green", "position":"P"}}

    {"id":4, "name": "Grace", "team":{"code":"green", "position":"P"}}

    {"id":5, "name": "Steven", "team":[
        {"code":"green", "position":"S"},
        {"code":"red", "position":"S"}]}

    {"id":6, "name": "Josephine", "team":{"code":"red", "position":"S"}}

    {"id":7, "name": "Sydney", "team":[
        {"code":"red", "position":"S"},
        {"code":"green", "position":"P"}]}

我想查询ES中红队的人,位置P. 随着请求

curl -XPOST 'http://localhost:9200/teams/aff/_search' -d '{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "team.code": "red"
          }
        },
        {
          "match": {
            "team.position": "P"
          }
        }
      ]
    }
  }
}'

我的错误结果。 ES给出了

"name": "John",
"team":
  { "code": "red", "position": "P" }
and 
"name": "Sydney",
"team":
 [
  { "code": "red",   "position": "S"},
  { "code": "green", "position": "P"}
 ]

对于最后一个条目,ES在第一个记录中取得属性代码= red,并在第二个记录中取得属性position = P.

如何指定搜索必须与相同记录中的2个两个术语匹配(嵌套记录列表内或不是嵌套记录列表)?

事实上,好的答案只是文件1,约翰。

以下是创建数据集的要点: https://gist.github.com/flrt/4633ef59b9b9ec43d68f

提前致谢

2 个答案:

答案 0 :(得分:3)

索引文档时

{
  "name": "Sydney",
  "team": [
    {"code": "red", "position": "S"},
    {"code": "green","position": "P"}
  ]
}

ES为您的字段隐式创建inner object(在特定示例中为team)并将其展平为

结构
{
  'team.code': ['red', 'green'],
  'team.position: ['S', 'P']
}

所以你丢了订单。为避免这种情况,您需要明确地放置nested映射,一如既往地索引文档并使用nested查询

查询它们

所以,这个

PUT so/nest/_mapping
{
  "nest": {
    "properties": {
      "team": {
        "type": "nested"
      }
    }
  }
}

PUT so/nest/
{
  "name": "Sydney",
  "team": [
    {
      "code": "red",
      "position": "S"
    },
    {
      "code": "green",
      "position": "P"
    }
  ]
}

GET so/nest/_search
{
  "query": {
    "nested": {
      "path": "team",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "team.code": "red"
              }
            },
            {
              "match": {
                "team.position": "P"
              }
            }
          ]
        }
      }
    }
  }
}

将导致空命中。

进一步阅读关系管理:https://www.elastic.co/blog/managing-relations-inside-elasticsearch

答案 1 :(得分:1)

您可以使用Nested Query,以便您的搜索单独发生在team数组中的子文档中,而不是整个文档中。

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "team",
            "query": {
              "bool": {
                "must": [
                  { "match": { "team.code": "red"   } },
                  { "match": { "team.position": "P" } }
                ]
              }
            }
          }
        }
      ]
    }
  }
}