ElasticSearch跨多种类型的NEST查询

本文关键字:NEST 查询 类型 种类 ElasticSearch | 更新日期: 2023-09-27 17:54:00

给定以下POCOs:

public class Dog
{
    public string Name { get; set; }
}
public class Cat
{
    public string Name { get; set; }
    public bool Enabled { get; set; }
}

我想执行一个查询,返回所有启用的狗和猫。

elastic文档提供了以下示例,但没有详细说明如何使用Bool带查询或过滤器上下文来跨多种类型搜索特定字段值:

.Search<object>(s => s
    .Size(100)
    .Type(Types.Type(typeof(Dog), typeof(Cat)))                
    .Query(...)

如何执行查询?

ElasticSearch跨多种类型的NEST查询

我们可以查询元数据_type字段,并将其与其他字段的查询结合起来。这里有一个例子。我们将创建100只猫和100只狗,将每只猫设置为禁用

void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var defaultIndex = "pets";
    var connectionSettings = new ConnectionSettings(pool)
            .DefaultIndex(defaultIndex);
    var client = new ElasticClient(connectionSettings);
    if (client.IndexExists(defaultIndex).Exists)
        client.DeleteIndex(defaultIndex);
    client.CreateIndex(defaultIndex, ci => ci
        .Mappings(m => m
            .Map<Dog>(d => d.AutoMap())
            .Map<Cat>(c => c.AutoMap())
        )
    );
    var dogs = Enumerable.Range(1, 100).Select(i => new Dog
    {
        Name = $"Dog {i}"
    });
    client.IndexMany(dogs);
    var cats = Enumerable.Range(1, 100).Select(i => new Cat
    {
        Name = $"Cat {i}",
        Enabled = i % 2 == 0 ? false : true
    });
    client.IndexMany(cats);
    client.Refresh(defaultIndex);
    client.Search<object>(s => s
        .Size(100)
        .SearchType(SearchType.Count)
        .Type(Types.Type(typeof(Dog), typeof(Cat)))
        .Query(q => 
            (+q.Term("_type", "cat") && +q.Term("enabled", true)) ||
            +q.Term("_type", "dog")
        )
    );
}

搜索查询利用了操作符重载;一元+运算符将意味着查询将包装在bool查询filter中,类似地,&&将包装成bool查询must(或filter,因为我们也使用+一元运算符使其成为过滤器),||将包装成bool查询should。结果执行的查询看起来像

{
  "size": 100,
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "filter": [
              {
                "term": {
                  "_type": {
                    "value": "cat"
                  }
                }
              },
              {
                "term": {
                  "enabled": {
                    "value": true
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "filter": [
              {
                "term": {
                  "_type": {
                    "value": "dog"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}
收益率

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 150,
    "max_score" : 0.0,
    "hits" : [ ]
  }
}

这只是一个计数,但是如果您要查看文档,就会发现所有的狗和猫都是启用的