Elasticsearch 不适用于 'not_analyzed' 索引

Elasticsearch not working with 'not_analyzed' index

我不明白为什么 elasticsearch 不使用 not_analysed 索引进行搜索。我的模型中有以下设置,

settings index: { number_of_shards: 1 } do
      mappings dynamic: 'false' do
        indexes :id
        indexes :name, index: 'not_analyzed'
        indexes :email, index: 'not_analyzed'
        indexes :contact_number
      end
    end

    def as_indexed_json(options = {})
      as_json(only: [ :id, :name, :username, :user_type, :is_verified, :email, :contact_number ])
    end

而且我在elasticsearch的映射是正确的,如下。

{
  "users-development" : {
    "mappings" : {
      "user" : {
        "dynamic" : "false",
        "properties" : {
          "contact_number" : {
            "type" : "string"
          },
          "email" : {
            "type" : "string",
            "index" : "not_analyzed"
          },
          "id" : {
            "type" : "string"
          },
          "name" : {
            "type" : "string",
            "index" : "not_analyzed"
          }
        }
      }
    }
  }
}

但问题是,当我在未分析的字段(姓名和电子邮件,因为我希望它们不被分析)上进行搜索时,它只会搜索全词。就像下面的例子一样,它应该有 return John、Johny 和 Tiger,所有 3 条记录。但它只有returns 2条记录。

我正在搜索如下

  settings = {
    query: {
      filtered: {
        filter: {
          bool: {
            must: [
              { terms: { name: [ "john", "tiger" ] } },
            ]
          }
        }
      }
    },
    size: 10
  }

  User.__elasticsearch__.search(settings).records

这就是我在回调 after_save

中为我的用户对象创建索引的方式
User.__elasticsearch__.client.indices.create(
                index: User.index_name,
                id: self.id,
                body: self.as_indexed_json,
              )

一些应该匹配的文档

[{
      "_index" : "users-development",
      "_type" : "user",
      "_id" : "670",
      "_score" : 1.0,
      "_source":{"id":670,"email":"john@monkeyofdoom.com","name":"john baba","contact_number":null}
    },
    {
          "_index" : "users-development",
          "_type" : "user",
          "_id" : "671",
          "_score" : 1.0,
          "_source":{"id":671,"email":"human@monkeyofdoom.com","name":"Johny Rocket","contact_number":null}
        }

    , {
          "_index" : "users-development",
          "_type" : "user",
          "_id" : "736",
          "_score" : 1.0,
          "_source":{"id":736,"email":"tiger@monkeyofdoom.com","name":"tiger sherof", "contact_number":null}
        } ]

有什么建议吗

根据文档 term query

The term query finds documents that contain the exact term specified in the inverted index.

您正在搜索 john,但 none 的文档包含 john,这就是为什么您没有得到任何结果的原因。您可以将字段 analysed 然后应用 query string 或搜索确切的术语。

参考https://www.elastic.co/guide/en/elasticsearch/reference/2.x/query-dsl-term-query.html了解更多详情

我认为使用 keyword toknizer combined with lowercase filter 比使用 not_analyzed 会得到想要的结果。

john*Johny 不匹配的原因是区分大小写。 此设置将起作用

{
  "settings": {
    "analysis": {
      "analyzer": {
        "keyword_analyzer": {
          "type": "custom",
          "filter": [
            "lowercase"
          ],
          "tokenizer": "keyword"
        }
      }
    }
  },
  "mappings": {
    "my_type": {
      "properties": {
        "name": {
          "type": "string",
          "analyzer": "keyword_analyzer"
        }
      }
    }
  }
}

现在 john* 将匹配 johny。如果您有各种要求,您应该使用 multi-fieldsterms query 对于 john 不会给你 john baba 因为在倒排索引里面没有标记 as john.您可以在一个字段上使用标准分析器,在另一个字段上使用关键字分析器。