【问题标题】:Difficulty running a basic Elasticsearch query against dataset难以对数据集运行基本的 Elasticsearch 查询
【发布时间】:2019-03-29 07:22:35
【问题描述】:

我正在尝试对具有基本莎士比亚数据集的弹性搜索集群运行布尔查询。我已经交叉检查了许多资源,一切似乎都是正确的,但是当我运行它时,speech_number 分数 OR 操作没有按预期工作。

我查看了有关 elasticsearch 布尔查询的各种教程和文档,但我仍然没有发现逻辑为什么不能按预期工作。

"query": {
            "bool": {
                "must": [
                    {
                        "match": {"play_name": "Henry IV"}
                    },
                    {
                        "bool": {
                            "should": [
                                {"range": {"speech_number": {"lte": 50}}},
                                {"range": {"speech_number": {"gte": 4}}}
                            ]
                        }
                    }
                ]
            }
        }
    }

我对其运行查询的shakespear.json 文件示例如下:

{"line_id":1658,"play_name":"Henry IV","speech_number":26,"line_number":"3.1.108","speaker":"MORTIMER","text_entry":"Yea, but"}
{"index":{"_index":"shakespeare","_type":"line","_id":1658}}
{"line_id":1659,"play_name":"Henry IV","speech_number":26,"line_number":"3.1.109","speaker":"MORTIMER","text_entry":"Mark how he bears his course, and runs me up"}
{"index":{"_index":"shakespeare","_type":"line","_id":1659}}
{"line_id":1660,"play_name":"Henry IV","speech_number":26,"line_number":"3.1.110","speaker":"MORTIMER","text_entry":"With like advantage on the other side;"}
{"index":{"_index":"shakespeare","_type":"line","_id":1660}}
{"line_id":1661,"play_name":"Henry IV","speech_number":26,"line_number":"3.1.111","speaker":"MORTIMER","text_entry":"Gelding the opposed continent as much"}
{"index":{"_index":"shakespeare","_type":"line","_id":1661}}
{"line_id":1662,"play_name":"Henry IV","speech_number":26,"line_number":"3.1.112","speaker":"MORTIMER","text_entry":"As on the other side it takes from you."}
{"index":{"_index":"shakespeare","_type":"line","_id":1662}}
{"line_id":1663,"play_name":"Henry IV","speech_number":27,"line_number":"3.1.113","speaker":"EARL OF WORCESTER","text_entry":"Yea, but a little charge will trench him here"}
{"index":{"_index":"shakespeare","_type":"line","_id":1663}}
{"line_id":1664,"play_name":"Henry IV","speech_number":27,"line_number":"3.1.114","speaker":"EARL OF WORCESTER","text_entry":"And on this north side win this cape of land;"}
{"index":{"_index":"shakespeare","_type":"line","_id":1664}}
{"line_id":1665,"play_name":"Henry IV","speech_number":27,"line_number":"3.1.115","speaker":"EARL OF WORCESTER","text_entry":"And then he runs straight and even."}
{"index":{"_index":"shakespeare","_type":"line","_id":1665}}
{"line_id":1666,"play_name":"Henry IV","speech_number":28,"line_number":"3.1.116","speaker":"HOTSPUR","text_entry":"Ill have it so: a little charge will do it."}
{"index":{"_index":"shakespeare","_type":"line","_id":1666}}
{"line_id":1667,"play_name":"Henry IV","speech_number":29,"line_number":"3.1.117","speaker":"GLENDOWER","text_entry":"Ill not have it alterd."}
{"index":{"_index":"shakespeare","_type":"line","_id":1667}}
{"line_id":1668,"play_name":"Henry IV","speech_number":30,"line_number":"3.1.118","speaker":"HOTSPUR","text_entry":"Will not you?"}
{"index":{"_index":"shakespeare","_type":"line","_id":1668}}
{"line_id":1669,"play_name":"Henry IV","speech_number":31,"line_number":"3.1.119","speaker":"GLENDOWER","text_entry":"No, nor you shall not."}
{"index":{"_index":"shakespeare","_type":"line","_id":1669}}
{"line_id":1670,"play_name":"Henry IV","speech_number":32,"line_number":"3.1.120","speaker":"HOTSPUR","text_entry":"Who shall say me nay?"}
{"index":{"_index":"shakespeare","_type":"line","_id":1670}}
{"line_id":1671,"play_name":"Henry IV","speech_number":33,"line_number":"3.1.121","speaker":"GLENDOWER","text_entry":"Why, that will I."}

预期结果应该是:play_name AND (speech_number =4) 我得到的是:play_name AND (speech_number = 4)

【问题讨论】:

  • 你试过过滤嵌套布尔查询吗?
  • 是的,我尝试使用过滤器但没有成功
  • @DejanMarić,我再次尝试使用过滤查询,但我尝试使用“constant_score”并且它有效。我之前没有使用 constant_score 。此外,我实际上是 ES 世界的初学者,如果您能向我解释为什么它可以使用 filter 而不是我以前使用的方法,是否有可能?非常感谢您的帮助:)

标签: elasticsearch


【解决方案1】:

你是对的,查询正在做:

  • 必须匹配: 1) 来自“亨利四世”的任何词语 [1 见下文] 2) speech_number speech_number >=4

Elasticsearch 也在做的是分配一个分数:所以 must 中的所有内容都应该匹配,然后should 查询中的所有内容都会提升结果(should 中的至少一个必须匹配)

要提高更高的speech_number 更多(不要这样做),您可以有更多匹配的should 语句:

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": { 
                        "play_name": "Henry IV"
                    }
                },

                {
                    "bool": {
                        "should": [
                            {
                                "range": {
                                    "speech_number": { "lte": 50 }
                                }
                            },

                            {
                                "range": {
                                    "speech_number": { "lte": 40 }
                                }
                            },

                            {
                                "range": {
                                    "speech_number": { "lte": 30 }
                                }
                            },

                            ...
                        ]
                    }
                }
            ]
        }
    }
}

所以问题的一部分可能是lte: 50 将允许 gte:4 >50。但我在你的结果中没有看到任何局外人。如果是下单。 range 还允许提升 (https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html),因此您不必编写多个范围:

{
    "query": {
        "bool": {
            "must": [
                {
                    "match": { 
                        "play_name": "Henry IV",
                        "operator": "and
                    }
                },

                {
                    "bool": {
                        "should": [
                            {
                                "range": {
                                    "speech_number": { 
                                        "gte": 25,
                                        "lte": 50,

                                        "boost": 3
                                    }
                                }
                            },

                            {
                                "range": {
                                    "speech_number": { 
                                        "gte": 4,
                                        "lte": 50
                                    }
                                }
                            }
                        ]
                    }
                }
            ]
        }
    }
}

[1*] 匹配默认为 OR:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html 如果您的数据是结构化的,那么您想要的更多的是 Term 或添加运算符 and。不是你的问题:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    相关资源
    最近更新 更多