【问题标题】:ElasticSearch query combining string match and nested field value结合字符串匹配和嵌套字段值的 ElasticSearch 查询
【发布时间】:2020-02-24 00:52:47
【问题描述】:

我有一个如下所示的 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 还很陌生,非常渴望就我应该用来实现这一目标的查询/结构类型获得意见。

有什么建议吗?

谢谢。

【问题讨论】:

  • 您能否提供您的索引映射以及您尝试过的任何我们可以构建解决方案的东西
  • 用索引映射更新了我的问题;我正在阅读“嵌套查询”,但目前我没有部分解决方案。根据输出要求和数据的外观,寻找有关使用哪种查询以及如何对数据进行结构化/索引的建议。
  • 看起来您提供了部分映射,我看不到日期和投诉字段的映射,如果您可以与所有必需的 API 共享邮递员集合以快速重现您的问题,那就太好了
  • 道歉;我的索引映射实际上是无效的。 ES 仍然为我返回结果,所以似乎不是问题。我又更新了。感谢您为调查所做的努力,但在这个阶段,我不太愿意与第三方共享对 API 的访问权限。
  • 我们不需要访问您的 API,我们只需要最少的信息来调试问题 :-)

标签: elasticsearch


【解决方案1】:

看来我可以通过以下查询解决这个问题:


"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"} }
                    ]
                }
            }
        }
      }
    }
  }

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

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

据我了解,我的查询的第一部分表明结果“必须”在 2 个字段之一中包含与我的查询匹配的字符串。

第二部分是嵌套查询。虽然我的数据看起来是一个日期,但它实际上像一个类别一样被存储和查询,所以我将投诉周期类型切换为“关键字”类型而不是“文本”。这使我可以在“术语”查询中使用它(精确文本匹配,分类)。

由于嵌套查询是“应该”,因此结果不必匹配,但如果匹配,则应该提高分数并将其推到结果列表的更靠前。

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

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

我可能需要稍后添加。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    • 2017-12-03
    • 2017-09-17
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    • 2020-08-21
    相关资源
    最近更新 更多