【问题标题】:Confusions about the Elasticsearch json dsl query structure关于 Elasticsearch json dsl 查询结构的困惑
【发布时间】:2015-10-25 19:29:54
【问题描述】:

在 elasticsearch dsl 查询语法文档的许多地方,包装器 json 查询在解释中被跳过,可能是为了减少文档大小。但是当我一直在浏览文档时,它一直令人困惑。 在 json 查询中可以或应该去哪里的正式规则是什么? 换句话说,我正在尝试找到所有弹性查询中通用的标准或模式,因为我需要构建一个内部api来查询弹性。是否有一个模板包含"bool":{}filter等内部的所有语法组件"query': {},我可以在其中填写相关部分还在运行?

【问题讨论】:

    标签: elasticsearch elastic-stack


    【解决方案1】:

    我也发现 Elastic 的 DSL 结构令人困惑,但在运行了数百个查询之后你就习惯了。

    以下是不同类型查询的几个(完整)示例,希望这将有助于解决您可能遇到的一些问题,请随时在评论中添加场景,我会添加更多示例。

    这是标准查询的样子:

    {
        "query": {
            "bool": {
                "must": {
                    "match": {
                        "message": "abcd"
                    }
                }
            }
        }
    }
    

    但是,这是过滤后查询的样子,您会在过滤 elasticsearch 时注意到结构发生了变化:

    {
        "query": {
            "filtered": {
                "filter": {
                    "term": {
                        "message": "abcd"
                    }
                }
            }
        }
    }
    

    (Read more about the difference between Filters and Queries)

    同时具有过滤器和查询的查询如下所示:

    {
        "query": {
            "filtered": {
                "filter": {
                    "term": {
                        "message": "abcd"
                    }
                },
                "query": {
                    "bool": {
                        "must": {
                            "match": {
                                "message2": "bbbb"
                            }
                        }
                    }
                }
            }
        }
    }
    

    以下是运行具有多个条件的过滤器的方法:

    {
        "query": {
            "filtered": {
                "filter": {
                    "and": [
                        {
                            "term": {
                                "message": "abcd"
                            }
                        },
                        {
                            "term": {
                                "message2": "abcdd"
                            }
                        }
                    ]
                }
            }
        }
    }
    

    还有一个更复杂的过滤器:

    {
        "query": {
            "filtered": {
                "filter": {
                    "and": [
                        {
                            "term": {
                                "message": "abcd"
                            }
                        },
                        {
                            "term": {
                                "message2": "abcdd"
                            }
                        },
                        {
                            "or": [
                                {
                                    "term": {
                                        "message3": "abcddx"
                                    }
                                },
                                {
                                    "term": {
                                        "message4": "abcdd2"
                                    }
                                }
                            ]
                        }
                    ]
                }
            }
        }
    }
    

    使用聚合的简单查询:

    {
        "query": {
            "filtered": {
                "filter": {
                    "term": {
                        "message": "abcd"
                    }
                }
            }
        },
        "aggs": {
            "any_name_will_work_here": {
                "max": {
                    "field": "metric1"
                }
            }
        }
    }
    

    query_string 查询:

    {
        "query": {
            "query_string": {
                "default_field": "message",
                "query": "this AND that"
            }
        }
    }
    

    使用 DSL 时需要考虑的其他一些事项:

    1. 您可以在顶层(查询上方)添加size 参数,该参数将确定要返回的结果数量。如果您只需要文档计数,您可以使用 "size": 0,它不会得到任何结果,只会得到元数据。
    2. 然而,当使用aggs 时,size 参数有一个扭曲,在aggs 字段内设置"size": 0 将告诉ES 获取ALL 聚合桶
    3. DSL 结构有例外,在我的示例中,我通常使用terms,但range 的结构有点不同。

    【讨论】:

    • 谢谢。所以在过滤器中,你不能有 musts、shoulds 和 must_nots 吗?你只能有AND OR等?如果是这样,我有两个问题。过滤器中的 AND OR 和查询中的布尔(必须、应该等)有什么区别?还有 query_string 查询呢?可以进入过滤器还是必须在查询中?看起来,过滤器也可以接受查询。这让这个疯狂的人感到困惑。
    • 是的,过滤器只接受and/or,查询接受must/should,它们完全相同(并且=必须,或=应该)。您应该选择查询而不是过滤器的原因是我之前链接到的那个 SO 答案。 query_string 仅在查询部分下,这也是“标准”查询结构中的一个例外。我现在将为其添加一个示例。您可以在“过滤器”下嵌套“查询”,这基本上允许您在同一过滤查询中组合查询的功能。这很复杂,我知道,你是对的 ;(
    • 你的意思是说我应该对查询使用过滤器,对吧?由于过滤器的缓存?
    • 是的。过滤后的查询被缓存并且效率更高,因为 ES 不需要为它们计算分数。但是,您可能希望对结果进行评分,例如,如果您在分析的字段上使用全文搜索。
    • 谢谢!假设我此时不关心分数并决定使用过滤器,我不能将过滤器包装到查询中吗?如果我需要它,那会给我分数,或者我在这里遗漏了什么?
    猜你喜欢
    • 1970-01-01
    • 2013-12-31
    • 2019-02-20
    • 2015-01-30
    • 1970-01-01
    • 2020-04-24
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    相关资源
    最近更新 更多