我们有一个Elasticsearch索引,其中包含要按标题和描述搜索的产品目录。
我们希望它具有以下约束:
我试图创建这样的查询,但结果确实不准确。有时会找到完全无关的东西。我认为这是由于通配符查询。
另外,我认为必须为“ created_at”评分提供一个更优雅的解决方案。对?
我正在使用Elasticsearch 6.2
这是我当前的代码。我很高兴看到一个优雅的解决方案:
{
"sort": [
{
"_score": {
"order": "desc"
}
}
],
"min_score": 0.3,
"size": 12,
"from": 0,
"query": {
"bool": {
"filter": {
"terms": {
"category_id": [
"212",
"213"
]
}
},
"should": [
{
"match": {
"title_completion": {
"query": "Development",
"boost": 20
}
}
},
{
"wildcard": {
"title": {
"value": "*Development*",
"boost": 1
}
}
},
{
"wildcard": {
"title_completion": {
"value": "*Development*",
"boost": 10
}
}
},
{
"match": {
"title": {
"query": "Development",
"operator": "and",
"fuzziness": 1
}
}
},
{
"range": {
"created_at": {
"gte": 1563264817998,
"boost": 11
}
}
},
{
"range": {
"created_at": {
"gte": 1563264040398,
"boost": 4
}
}
},
{
"range": {
"created_at": {
"gte": 1563256264398,
"boost": 1
}
}
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
首先,构建返回相关结果的请求通常是一项艰巨的任务。在不知道文件内容的情况下是无法完成的。也就是说,我可以给您提示来满足您的要求并避免不相关的结果。
您可以像在查询中那样使用,boost与描述相比,标题匹配更加重要。
您应该使用AUTO模糊字段的值来根据术语的长度定义不同的模糊度值。例如,默认情况下,少于 3 个字母的术语(最常见的术语,其中字母的更改可能导致不同的单词)将不允许更改。超过 3 个字母的术语将允许进行 1 次更改,超过 5 个字母将允许进行 2 次更改。您可以根据您的测试更改此行为。
should在语句中使用子句bool。语句中的子句should不会过滤文档(除非另有说明)。子句中的查询should仅用于增加分数。
在语句中使用mustoffilter子句bool可确保所有文档都验证约束。如果您不希望子查询对分数做出贡献(我相信这是您的情况),请使用filter而不是match因为filter将能够缓存结果。您的查询符合此要求。
您应该使用function score带有衰减函数的a 。如果您不清楚衰减函数,您可以跳过文档中的方程并跳转到不言自明的图。以下查询是使用高斯衰减函数的示例。
{
"function_score": {
// Name of the decay function
"gauss": {
// Field to use
"created_at": {
"origin": "now", // "now" is the default so you can omit this field
"offset": "1d", // Values with less than 1 day will not be impacted
"scale": "10d", // Duration for which the scores will be scaled using a gauss function
"decay" : 0.01 // Score for values further than scale
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
避免通配符查询:如果使用*它们,效率不高,并且会消耗大量内存。如果您希望能够搜索术语的一部分(当用户搜索“house”时查找“penthouse”),您应该使用ngram分词器创建一个子字段,并使用该子字段编写一个标准match查询。
避免设置最低分数:分数是一个相对值。小分或高分并不意味着该文档相关或不相关。您可以阅读这篇有关该主题的文章。
小心fuzzy查询:模糊会产生大量噪音并使用户感到困惑。一般来说,我建议增加AUTO模糊的默认阈值,并接受某些拼写错误的查询不会返回良好的结果。通常,与理解为什么他有完全不相关的结果相比,用户检测输入中的拼写错误更容易。
这只是一个示例,您需要根据您的数据进行调整。
{
"size": 12,
"query": {
"bool": {
"filter": {
"terms": {
"category_id": <CATEGORY_IDS>
}
},
"should": [
{
"match": {
"title": {
"query": <QUERY>,
"fuzziness": AUTO:4:12,
"boost": 3
}
}
},
{
"match": {
"title_completion": {
"query": <QUERY>,
"boost": 1
}
}
},
{
"match": {
// title_completion field with ngram tokenizer
"title_completion.ngram": {
"query": <QUERY>,
// Use lower boost because it match only partially
"boost": 0.5
}
}
}
]
},
"function_score": {
// Name of the decay function
"gauss": {
// Field to use
"created_at": {
"origin": "now", // "now" is the default so you can omit this field
"offset": "1d", // Values with less than 1 day will not be impacted
"scale": "10d", // Duration for which the scores will be scaled using a gauss function
"decay" : 0.01 // Score for values further than scale
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
127 次 |
| 最近记录: |