为什么前缀返回没有特定前缀的文档?

时间:2014-10-01 09:25:01

标签: elasticsearch

我想只返回名字以" pizza"开头的文件。这就是我所做的:

{
  "query": {
    "filtered": {
      "filter": {
        "prefix": {
          "name": "pizza"
        }
      }
    }
  }
}

但我已经收到了这三份文件:

{
"name": "Viana Pizza",
"city": "Mashhad",
"address": "Vakil abad",
"foods": ["Pizza"],
"salad": true,
"rate": 5.0
}

{
"name": "Pizza Pizza",
"city": "Mashhad",
"address": "Bahar st",
"foods": ["Pizza"],
"salad": true,
"rate": 8.5
}

{
"name": "Reza Pizza",
"city": "Tehran",
"address": "Vali Asr",
"foods": ["Pizza"],
"salad": true,
"rate": 7.5
}

正如你所看到的,只有其中一个人有#14;披萨"在名称字段的开头。 怎么了?

2 个答案:

答案 0 :(得分:2)

可能最简单的解释是,你没有提供实际的映射,就是你有一个" name" field as" string"和"分析" (默认)。这意味着" Reza Pizza"将转变为" reza"和#34;披萨"术语

您的过滤器将与术语匹配,而不是与整个字段匹配。因为ES在使用标准映射时分析字段和表单术语。

你需要改变你的名字"字段到" not_analyzed"或添加另一个字段来镜像" name"但是这个镜像领域是" not_analyzed"。此外,对于文字"披萨" (小写)在这种情况下工作,你需要创建一个自定义分析器。

下面是镜像字段的解决方案:

PUT /pizza
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_keyword_lowercase_analyzer": {
          "type": "custom",
          "tokenizer": "keyword",
          "filter": ["lowercase"]
        }
      }
    }
  },
  "mappings": {
    "restaurant": {
      "properties": {
        "name": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "analyzer": "my_keyword_lowercase_analyzer"
            }
          }
        }
      }
    }
  }
}

在搜索中你需要使用镜像字段:

GET /pizza/restaurant/_search
{
  "query": {
    "filtered": {
      "filter": {
        "prefix": {
          "name.raw": "pizza"
        }
      }
    }
  }
}

答案 1 :(得分:2)

这完全是关于Elasticsearch analyzers的。让我们阅读prefix过滤器上的documentation

Filters documents that have fields containing terms with a specified prefix (not analyzed).

在这里,我们可以看到此过滤器与字词匹配,而不是整个字段值。索引文档时,ES会使用分析器将字段值拆分为术语。默认分析器按空格分割值并将部件转换为lowercse。因此,所有三个结果都在名称字段中包含术语披萨,而pizza字词与pizza前缀完全匹配。如果您希望按原样匹配字段值,我建议您将名称字段映射为not_analyzed