是否可以使用 Nest 将查询列表传递给 ElasticSearch?

Posted

技术标签:

【中文标题】是否可以使用 Nest 将查询列表传递给 ElasticSearch?【英文标题】:Is it possible to pass a list of queries to ElasicSearch using Nest? 【发布时间】:2021-12-05 14:12:56 【问题描述】:

我需要将复杂的查询传递给 Elasticsearch。在这个查询中会有很多范围条件,主要是日期范围。

示例如下:

query = "module : ('mod45') AND code : ('667', '456') AND startTime:[2020-10-18T13:42:17 TO 2021-10-18T13:42:17] AND endTime:[2021-02-18T13:42:17 TO 2021-09-18T13:42:17]"

modulecodestartTimeendTime 是列名)

我有以下 Elasticsearch 功能:

public async Task<IEnumerable<T>> GetQueryStringData<T>(string index, string query) where T : class

    var client = GetClient();

    var response = await client.SearchAsync<T>(s => s
        .Index(index)
        .Query(x => x.QueryString(a => a.Query(query))).Size(DefaultResultsSize));

    return response?.Documents;

是否可以更改此功能,使其可以在没有“AND”连接器的情况下接收查询条件列表?

类似这样的:

var queryList = new List<string>();

queryList.Add("module : ('mod45')");
queryList.Add("code : ('667', '456')");
queryList.Add("startTime:[2020-10-18T13:42:17 TO 2021-10-18T13:42:17]");
queryList.Add("endTime:[2021-02-18T13:42:17 TO 2021-09-18T13:42:17]");

编辑:假设我将有 100 个这样的查询,所以 lambda 在这里不起作用

【问题讨论】:

【参考方案1】:

您可以尝试使用 NEST 的 Fluent API,它使用 lambda 表达式来构造查询。

var moduleList = new List<string>();
moduleList.Add("mod45");
var codeList = new List<string>();
codeList.Add("667");
codeList.Add("456");

var response = await client.SearchAsync<T>(s => s
        .Index(index)
        .Query(q => q
                .Bool(b => b
                                .Must(
                                    m => m
                                        .Terms(t => t.Field("module").Terms(moduleList)),
                                    m => m
                                        .Terms(t => t.Field("code").Terms(codeList)),
                                    m => m.Bool(bs => bs
                                            .Must(ms => ms.TermRange(r => r.Field(f => f.startTime)
                                                  .GreaterThanOrEquals(new DateTime(2020, 10, 18))
                                                  .LessThanOrEquals(new DateTime(2021, 10, 18)))
                                            )
                                        ),
                                    m => m.Bool(bs => bs
                                            .Must(ms => ms.TermRange(r => r.Field(f => f.endTime)
                                                  .GreaterThanOrEquals(new DateTime(2021, 02, 18))
                                                  .LessThanOrEquals(new DateTime(2021, 09, 18)))
                                            )
                                        )
                                )
                            )
                        )    
       .DefaultOperator(Operator.And)
       .Size(DefaultResultsSize)); 

【讨论】:

以上是关于是否可以使用 Nest 将查询列表传递给 ElasticSearch?的主要内容,如果未能解决你的问题,请参考以下文章

将列名列表传递给 psycopg2 中的查询

ElasticSearch NEST笔记

将对象序列化为 JSON,然后使用 NEST 在弹性搜索中发送查询

JPA将列表传递给命名本机查询中的IN子句

ElasticSearch NEST笔记

是否可以在 JDBC 中执行“字段 IN 列表”查询,并将列表作为参数传递?