我只想返回名称以“pizza”开头的文档。这是我所做的:

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

但是我有以下3个文档:
{
"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
}

如您所见,其中只有一个在名称字段的开头具有“披萨”。
怎么了?

最佳答案

鉴于您未提供实际映射,最简单的解释可能是将“名称”字段作为“字符串”和“已分析”(默认值)。这意味着“Reza Pizza”将被转换为“reza”和“pizza”术语。

而且您的过滤器将匹配条款,而不是整个字段。因为ES使用标准映射时会分析字段并形成术语。

您需要将“名称”字段更改为“not_analyzed”,或添加另一个字段来镜像“名称”,但此镜像字段必须为“not_analyzed”。另外,在这种情况下,为了使文本“pizza”(小写)起作用,您需要创建一个自定义分析器。

下面是带有mirror字段的解决方案:

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"
            }
          }
        }
      }
    }
  }
}

在搜索中,您需要使用mirror字段:
GET /pizza/restaurant/_search
{
  "query": {
    "filtered": {
      "filter": {
        "prefix": {
          "name.raw": "pizza"
        }
      }
    }
  }
}

关于elasticsearch - 为什么前缀返回没有特定前缀的文档?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26138128/

10-09 22:39