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-fields
。 terms query
对于 john 不会给你 john baba 因为在倒排索引里面没有标记 as john.您可以在一个字段上使用标准分析器,在另一个字段上使用关键字分析器。
我不明白为什么 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-fields
。 terms query
对于 john 不会给你 john baba 因为在倒排索引里面没有标记 as john.您可以在一个字段上使用标准分析器,在另一个字段上使用关键字分析器。