Elasticsearch短语匹配过滤器

时间:2015-08-31 09:45:55

标签: elasticsearch filter phrase

我有一个查询,按给定的时间间隔在文本字段中搜索给定的术语。我想在此查询中添加词组匹配,如何添加;例如,我会寻找“has parti”作为短语,但文字不应该有“ahmet”字样。我怎样才能做到这一点;代码在这里;

{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "terms": {
                "text": [
                  "has",
                  "parti"
                ]
              }
            },
            {
              "range": {
                "date": {
                  "gt": "2015-08-27",
                  "lte": "2015-08-28"
                }
              }
            }
          ]
        }
      }
    }
  }
}

2 个答案:

答案 0 :(得分:3)

Elasticsearch提供Phrase matching,但我认为你不能在filter中使用它,或者至少我没有设法让它工作。我有match_phrasequery的解决方案,以及text不包含ahmet的条件,而时间间隔保留在filter 。检查它是否足够好。

{
    "query": {
        "filtered": {
            "query": {
                "bool": {
                    "must": [
                        {
                            "match_phrase": {
                                "text": "has parti"
                            }
                        }
                    ],
                    "must_not": [
                        {
                            "match": {
                                "text": "ahmet"
                            }
                        }
                    ]
                }
            },
            "filter": {
                "bool": {
                    "must": [
                        {
                            "range": {
                                "date": {
                                    "gt": "2015-08-27",
                                    "lte": "2015-08-28"
                                }
                            }
                        }
                    ]
                }
            }
        }
    }
}

顺便说一下,你的date看起来像是被映射为字符串,否则你的请求会失败

  

ElasticsearchParseException [无法解析日期字段[2015-08-22],尝试了日期格式[date_time]和时间戳号];嵌套:IllegalArgumentException [格式无效:\“2015-08-22 \”太短]; }]

我建议使用正确的映射,但这与您的问题无关

更新:

刚刚回来添加we did the right thing:过滤器不适用于全文搜索

更新:

the filtered query has been deprecated起,在新版本中,应重写查询,以便在 bool 查询中移动过滤器:

{

    "query": {
        "bool": {
            "must": [{
                "match_phrase": {
                    "text": "has parti"
                }
            }],
            "must_not": [{
                "match": {
                    "text": "ahmet"
                }
            }],
            "filter": {
                "bool": {
                    "must": [{
                        "range": {
                            "date": {
                                "gt": "2015-08-27",
                                "lte": "2015-08-28"
                            }
                        }
                    }]
                }
            }
        }
    }

}

答案 1 :(得分:1)

您需要使用phrase match query。 但是,由于这是一个查询,当您正在寻找过滤器时,您需要将其包装在query filter中。

完成此操作后,您应该能够实现词组匹配过滤器。 接下来,当您需要否定时,将您的语句放在bool过滤器的must_not内。您可以使用术语过滤器。

所以最后你的查询看起来应该是这样的 -

{
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must_not": [
            {
              "term": {
                "title": "ahmet"
              }
            }
          ],
          "must": [
            {
              "range": {
                "date": {
                  "gt": "2015-08-27",
                  "lte": "2015-08-28"
                }
              }
            },
            {
              "constantScore": {
                "filter": {
                  "query": {
                    "match_phrase": {
                      "title": "has parti"
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}