结合字符串匹配和嵌套字段值的ElasticSearch查询



我有一个ElasticSearch查询,如下所示:

{
"query": {
"query_string": {
"query": "Lorem*",
"fields": ["search_names", "name^2"]
}
}
}

对照看起来像这样的文档。


{
"member_name" : "Lorem Ipsum",
"complaint_periods" : [
{
"period": "01/01/2001 - 31/12/2001",
"complaints": "10"
},
{
"period": "01/01/2002 - 31/12/2002",
"complaints": "0"
},
{
"period": "01/01/2003 - 31/12/2003",
"complaints": "3"
},
{
"period": "01/01/2004 - 31/12/2004",
"complaints": "100"
}
],
"search_names" : [
"Lorem Ipsum",
"dolor sit amet",
"varius augue",
"Aliquam fringilla"
]
}

因此,我可以根据文档名称的接近程度来检索文档,并搜索名称与我的查询的距离。

要求是,文本搜索框应检索与查询最匹配的名称,然而,如果名称相对相似,则在一段时间内投诉数量超过10的文档在搜索结果中的出现率应高于投诉数量低于10的文档。

因此,我需要传递一个时间段的密钥,例如"01/01/2001-31/12/2001",如果该时间段的投诉值>10,则提高文档得分。

当前索引映射如下所示。

"mappings": {
"properties": {
"member_name": {
"type": "text"
},
"search_names": {
"type": "text"
},
"complaint_periods": {
"type": "nested",
"properties": {
"period": {
"type": "text",
},
"complaints": {
"type": "integer"
}
}
}
}
}

我目前正在阅读嵌套查询作为一种可能的解决方案。。。但我对ES还很陌生,所以我很想了解我应该使用什么类型的查询/结构来实现这一点。

有什么建议吗?

谢谢。

所以我似乎能够通过以下查询解决这个问题:


"query": {
"bool": {
"must": {
"query_string": {
"query": "Lorem*",
"fields": ["search_names", "member_name^2"]
}
},
"should": {
"nested" : {
"path" : "complaint_periods",
"query" : {
"bool" : {
"should" : [
{ "term" : {"complaint_periods.period" : "01/01/2001 - 31/12/2001"} }
]
}
}
}
}
}
}

根据文档,我已经切换到使用布尔查询

与其他查询的布尔组合匹配的文档的查询

因此,正如我所理解的,我的查询的第一部分表明结果"必须"在两个字段中的一个字段中包含与我的查询匹配的字符串。

第二部分是嵌套查询。虽然我的数据看起来是一个日期,但它实际上像一个类别一样存储和查询,所以我将complaint_period类型切换为"关键字"类型,而不是"文本"类型。这使我可以在"term"查询中使用它(完全文本匹配,分类(。

由于嵌套查询是"应该",因此结果不必匹配,但如果匹配,则应提高分数,并将其进一步推高到结果列表中。

嵌套查询的文档也有一些示例,可以让我根据投诉数量进行提升,例如:

{ "range" : {"complaint_periods.complaints" : {"gt" : 5}} }

我可能需要稍后添加。

最新更新