如何在elasticsearch中运行组合查询和过滤?

How to run a combination of query and filter in elasticsearch?

我正在 django 的虚拟项目中尝试使用 elasticsearch。我正在尝试使用 django-elasticsearch-dsl 创建搜索页面。用户可以提供 titlesummaryscore 进行搜索。搜索应匹配用户提供的所有信息,但如果用户未提供有关某事的任何信息,则应跳过此搜索。

我是运行下面的代码来搜索所有的值

client = Elasticsearch()

s = Search().using(client).query("match", title=title_value)\
    .query("match", summary=summary_value)\
    .filter('range', score={'gt': scorefrom_value, 'lte': scoreto_value})

当我为所有字段提供值时,搜索将正常工作,但是如果我没有为 summary_value 提供值,尽管我希望搜索继续搜索其余字段的值,结果是它没有得到任何结果。

在用户不提供值的情况下,字段是否应该默认具有某些值?或者我应该如何处理?


更新 1 我尝试使用以下内容,但每次都 returns 无论输入什么,我都给出相同的结果。

s = Search(using=client)

if title:
    s.query("match", title=title)

if summary:
    s.query("match", summary=summary)


response = s.execute()

更新 2 我可以使用 to_dict().
进行打印 如果像下面这样那么 s 是空的

s = Search(using=client)
s.query("match", title=title)

如果是这样的话

s = Search(using=client).query("match", title=title)

然后它可以正常工作,但如果我添加 s.query("match", summary=summary) 它仍然没有任何作用。

我建议您使用 Python ES Client。它可以让您管理与集群相关的多项事情:设置映射、健康检查、执行查询等。

在其方法 .search() 中,正文参数是您发送查询的地方,您通常 运行 它 ({"query"...})。检查 Usage example.

现在,对于您的特定情况,您可以将查询模板存储在变量中。你首先开始,比方说,一个 "empty query" 只有 filter,就像:

query = {
    "query":{
        "bool":{
            "filter":[
            ]
        }
    }
}

从这里,您现在可以根据您拥有的参数构建查询。

这是:

#This would look a little messy, but it's useful ;)
#if parameter1 is not None or emtpy
#(change the if statement for your particular case)
if parameter1:
    query["query"]["bool"]["filter"].append({"term": {"field1": parameter1}})

对所有参数执行相同操作(对于字符串,使用 "term",对于范围,照常使用 "range")并在 .search() 的正文参数中发送查询,然后它应该如你所愿地工作。

希望对您有所帮助! :D

我在 Search example 中看到 django-elasticsearch-dsl 允许您在搜索后应用聚合,所以...

你的搜索 "staging" 怎么样?我可以考虑以下情况:

#first, declare the Search object
s = Search(using=client, index="my-index")

#if parameter1 exists
if parameter1:
    s.filter("term", field1= parameter1)

#if parameter2 exists
if parameter2:
    s.query("match", field=parameter2)

对所有参数执行相同的操作(每个参数都使用所需的方法),这样只有存在的参数才会出现在您的查询中。最后只是 运行

response = s.execute()

一切都应该如你所愿:D

您需要重新分配到 s:

if title:
    s = s.query("match", title=title)

if summary:
    s = s.query("match", summary=summary)