Elasticsearch将范围和术语连接到同一个数组项

时间:2017-05-30 15:26:35

标签: elasticsearch elastica elasticsearch-dsl

我有一个用户文档,其中包含一个名为体验的字段,这是一个对象数组,如:

{
  "experiences": [
    {
      "end_date": "2017-03-02",
      "is_valid": false
    },
    {
      "end_date": "2015-03-02",
      "is_valid": true
    }
  ]
}

使用此文档,我必须搜索结束日期为去年的用户,并且is_valid为true。 这时我有一个查询 - > bool ,我必须为 end_date 添加两个范围,为 is_valid 一词 >

{
  "query": {
    "bool": {
      "must": {
        "term": {
          "experiences.is_valid": true
        },
        "range": {
          "experiences.end_date": {
            "gte": "now-1y",
            "lte": "now"
          }
        },
      }
    }
  }
}

结果是该用户被选中是因为他在去年(第一个exp。)中有一个 end_date 而另一个是exp。 is_valid true 。 当然这不是我需要的,因为我需要 end_date is_valid 必须引用同一个对象,但我们如何在Elasticsearch上执行此操作?

映射

"experiences": {
  "properties": {
    "comment": {
      "type": "text",
      "fields": {
        "keyword": {
          "type": "keyword",
          "ignore_above": 256
        }
      }
    },
    "end_date": {
      "type": "date"
    },
    "id": {
      "type": "long"
    },
    "is_valid": {
      "type": "boolean"
    },
    "start_date": {
      "type": "date"
    }
  }
}

1 个答案:

答案 0 :(得分:3)

您需要将experiences类型更改为Nested data type

然后应用nested查询:

 {
 "query": {
  "nested": {
     "path": "experiences",
     "query": {
        "bool": {
           "must": [
              {
                 "term": {
                    "experiences.is_valid": true
                 }
              },
              {
                 "range": {
                    "experiences.end_date": {
                       "gte": "now-1y",
                       "lte": "now"
                    }
                 }
              }
           ]
        }
     }
   }
  }
 }

这是由于Elasticsearch中对象数组的展平方式。 研究更多here