我认为这种情况一定很常见,但我无法找到任何关于如何进步的线索。
我有一个包含单一类型Order
的弹性搜索索引。反过来,Order
包含Customer
个信息,例如firstName
,lastName
,middleName
(及其连接fullName
),例如
"order": {
// other stuff
"customer": {
"firstName": ...,
"lastName": ...,
"middleName": ...,
"fullName": "FirstName MiddleName LastName"
}
}
目的是提供订单搜索功能,包括按客户名称搜索。弹性的输入始终是单个查询字符串,包含在搜索框中键入的任何用户。问题是有一些脏数据(例如缺少firstName,交换名字和姓氏等),我不能依赖用户总是按特定顺序输入名称。
我尝试使用query_string
查询来实现这一目标:
"query_string": {
"query": "[User Input]*", // note asterisk here
"fields" : ["customer.firstName", "customer.lastName", "customer.middleName"],
"analyzer": "whitespace",
"use_dis_max": true,
"tie_breaker": 0.7,
"analyze_wildcard": true
}
在某些情况下,它可以很好地找到结果,但它对于脏数据肯定不够强大,例如:如果搜索“John Do”(不是拼写错误),它会找到John Doe的订单,但如果搜索“Doe John”则不会这样做。
所需的查询行为类似于多个字段上的match_phrase_prefix
whitespace
分析器,用于处理查询并在每个来自分析器的术语上做前缀。例如,John Doe
会变成类似["John*", "Doe*"]
的内容,并且每个都应用于
firstName
,lastName
,middleName
字段fullName
允许个别条款按任意顺序排列我真的很有弹性,所以我可能会遗漏一些非常简单的东西,或者没有足够的信心来编写非常复杂的查询。
修改:索引映射:http://pastebin.com/fuLLgHjB。目标字段尚未分析,因为:(1)我不是初始设置的人,(2)我真的不确定应该设置哪些现场分析器,所以这是问题的一部分。
答案 0 :(得分:2)
Elasticsearch有很好的默认值。您应该从默认值开始,并且只有在某些内容无法正常工作时才添加/更改设置。更简单更好。
设置映射时,字符串字段的默认值是分析它们。这是一件好事,因为将字符串分解为标记并确实是词干,因此您可以进行部分和模糊匹配。您不需要指定分析器; standard analyzer应该可以正常工作。未分析的字段意味着Elasticsearch不会对该字段做任何事情;这对于像分面(计算每个“John”,“Jon”和“Jonathan”的命令数量)这样的东西很有用,但对于一般的全文搜索来说并不多。如果您确实认为需要该字段的未分析版本,则可以包括分析的相同字段,而不是使用多字段分析;有关详细信息,请参阅multi-field docs。
这是一个示例映射;您甚至可能不需要生成fullName
字段。
"properties": {
"firstName": { "type": "string" },
"lastName": { "type": "string" },
"middleName": { "type": "string" },
"fullName": { "type": "string" }
}
分析字段后,查询中的字词顺序不必完全匹配,拼写不必完美等等。尝试最简单的查询,它应该可以正常工作:
{
"query": {
"query_string": {
"query": "John Doe",
"fields": [
"firstName",
"middleName",
"lastName"
]
]
}
}
}
如果它没有按照您期望的方式排序结果,您可以尝试使用AND替换查询字符串中的非尾随空格,以要求所有术语:John AND Doe