我需要确保字段的每个标记与用户搜索中的至少一个标记匹配。
为了简化起见,这是一个通用示例。
让 Store_Name = "Square Steakhouse"
当用户搜索 Square 或 Steakhouse 时,构建与该文档匹配的查询很简单。此外,通过将 kstem 过滤器附加到默认分析器,Steakhouses 也可能匹配。
{
"size": 30,
"query": {
"match": {
"Store_Name": {
"query": "Square",
"operator": "AND"
}
}
}
}
不幸的是,我需要匹配 Store_Name 字段的每个标记。我需要以下行为:
Query: Square Steakhouse Result: Match
Query: Square Steakhouses Result: Match
Query: Squared Steakhouse Result: Match
Query: Square Result: No Match
Query: Steakhouse Result: No Match
总结
- 不能选择使用 not_analyzed,因为我确实需要利用分析器的功能
- 我打算使用 kstem、自定义同义词、自定义 char_filter、小写过滤器以及标准分词器
但是,我需要确保字段的每个标记都匹配
这在 Elasticsearch 中可能吗?
最佳答案
这里有个好方法。
它并不完美,但在简单性、计算和存储方面是一个很好的折衷。
- 索引字段的标记数
- 获取搜索文本的标记数
- 执行过滤查询并强制结果之间的标记数相等
您需要使用分析 API 来获取 token 计数。确保使用与相关字段相同的分析器。这是一个获取 token 计数的 VB.NET 函数:
Private Function GetTokenCount(ByVal RawString As String, Optional ByVal Analyzer As String = "default") As Integer
If Trim(RawString) = "" Then Return 0
Dim client = New ElasticConnection()
Dim result = client.Post("http://localhost:9200/myindex/_analyze?analyzer=" & Analyzer, RawString) 'Submit analyze request usign PlainElastic.NET API
Dim J = JObject.Parse(result.ToString()) 'Populate JSON.NET JObject
Return (From X In J("tokens")).Count() 'returns token count using a JSON.NET JObject
End Function
您将希望在索引时使用它来存储相关字段的标记计数。确保 TokenCount 的映射中有一个条目
这是一个很好的 Elasticsearch 查询,用于利用这个新的 token 计数信息:
{
"size": 30,
"query": {
"filtered": {
"query": {
"match": {
"MyField": {
"query": "[query]",
"operator": "AND"
}
}
},
"filter": {
"term": {
"TokenCount": [tokencount]
}
}
}
}
}
- 将 [query] 替换为搜索词
- 将 [tokencount] 替换为搜索词中的标记数(使用上面的 GetTokenCount 函数
这确保所有匹配项至少与 MyField
中的标记一样多。
上述有一些缺点。例如,如果我们正在匹配字段“blue red”,并且用户搜索“blue blue”,上面将触发匹配。所以,你可能想使用 unique token filter .您可能还希望调整过滤器,以便
引用
关于elasticsearch - 如何构建 Elasticsearch 查询,以便匹配文档字段中的每个标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14629136/