如何在elasticsearch中的相同字段上创建精确值并匹配查询?

时间:2014-11-13 16:36:24

标签: filter elasticsearch

所以我有一个字段存储格式为number/year的值,如23 / 2014,24 / 2014,12 / 2015等等......

因此,如果此字段被映射为not_analyzed,我可以使用术语过滤器进行精确值搜索,如果我搜索该精确结构中的值(类似于1 / 2014,15 / 2014,。 ..)它的工作原理与sql equals(=)一样。

{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "processNumber": "11/2014"
        }
      }
    }
  }
}

因此,使用11 /或/ 2014之类的不同内容进行搜索将不会返回匹配。这很好。

但如果我将字段定义为not_analyzed,我就无法使用sql LIKE查询进行match_phrase类型搜索。

{
  "query": {
    "match_phrase": {
      "processNumber": "11/201"
    }
  }
}

在这种情况下,搜索11,11 /,/ 2014或2014应该返回命中,但它们不会。 问题是,如果该字段未映射为not_analyzed字段,则此查询有效。所以我似乎要么使用其中一个,问题是该字段应该支持不同查询的两个选项,我在这里遗漏了什么?

1 个答案:

答案 0 :(得分:14)

您可以使用映射中的fields属性以不同方式分析相同的字段 processNumber

例如,如果您想要分析和未分析的ProcessNumber版本,则映射将为:

 {
   "type_name": {
      "properties": {
         "processNumber": {
            "type": "string",
            "index": "not_analyzed",
            "fields": {
               "analyzed": {
                  "type": "string",
                  "index": "analyzed"
               }
            }
         }
      }
   }
}

将未分析的字段在查询中称为 processNumber

要参考分析的字段视图,请使用 processNumber.analyzed

对术语11 / 201,11等的查询将是:

示例过滤器:

 { "query" : { "filtered" : { "filter" : { "term" : { "processNumber" : "11/2014" } } } } }

术语过滤器它不会分析搜索字符串,因此在这种情况下输入将与字段反向索引匹配:11/2014对应字段。

示例Match_Phrase_prefix:

{ "query": { "match_phrase_prefix": { "processNumber": "11/201" } } }

match_phrase_prefix尝试检查短语中的最后一个词是否是索引中术语的前缀。 如果指定了分析器,它会分析搜索字符串。这就是您需要在此处使用该字段的未分析版本的原因。如果我们使用 processNumber.analyzed 搜索查询,例如 11-201,则11 | 201 也会匹配

示例匹配:

  { "query": { "match": { "processNumber.analyzed": "11" } } }

这是直截了当match,因为默认分析器(通常是标准分析器)会将11/2014标记为2014年第11期。

您可以使用analyze api查看默认分析器如何分析特定文本。

curl -XPOST "http://<machine>/_analyze?text=11/2014"