代码之家  ›  专栏  ›  技术社区  ›  David

C#Nest&Elasticsearch 6。x:如何筛选/计数嵌套字段(在内部列表中)

  •  1
  • David  · 技术社区  · 6 年前

    这是我的地图

    [ElasticsearchType(Name = "Topic")]
    public class Topic
    {
        [Number(NumberType.Integer, Coerce = true)]
        public EnumStatus Status { get; set; }
    
        [Nested]
        public List<KeywordValue> KeywordValues { get; set; }
    
    }
    
    [ElasticsearchType(Name = "KeywordValue")]
    public class KeywordValue
    {
        [Keyword]
        public string KeywordId { get; set; }
    
    }
    

    我有10份 Topic 在索引中,每个 KeywordValues 类型的属性/字段 List<KeywordValue> 包含5个 KeywordValue (列表中有5个元素)。

    9文件状态“ Enabled “;

    我试图计算每个嵌套中的元素总数 关键字值 领域返回的结果是9,但我想得到45(9*5)

    我正在这样做:

    var response = Topic.CurrentConnection.Search<Topic>(s => s
                    .Size(0)
                    .Aggregations(fa => fa
                        .Filter("filtered_aggs", f => f
                            .Filter(fd => fd.Term(t => t.Status, Topic.EnumStatus.Enabled))
                            .Aggregations(ta => ta
                                    .Nested("kv", n=>n.Path(p => p.KeywordValues)
                                        .Aggregations(aa => aa
                                            .ValueCount("vc", v => v.Field(vf => vf.KeywordValues.First().KeywordId))))
                                )
                            )
                        )
                );
    
    
            if (response.IsValid)
            {
                var agg = response.Aggregations.Nested("filtered_aggs");
                var n = agg.Nested("kv");
                var z = n.ValueCount("vc");
                result.Object = z.Value;
            }
    

    原始查询等效项:

    # Request:
    {
      "size": 0,
      "aggs": {
        "filtered_aggs": {
          "filter": {
            "term": {
              "Status": {
                "value": 0
              }
            }
          },
          "aggs": {
            "kv": {
              "nested": {
                "path": "KeywordValues"
              },
              "aggs": {
                "vc": {
                  "value_count": {
                    "field": "KeywordValues.KeywordId"
                  }
                }
              }
            }
          }
        }
      }
    }
    # Response:
    {
      "took" : 80,
      "timed_out" : false,
      "_shards" : {
        "total" : 5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : 10,
        "max_score" : 0.0,
        "hits" : [ ]
      },
      "aggregations" : {
        "filter#filtered_aggs" : {
          "doc_count" : 9,
          "nested#kv" : {
            "doc_count" : 9,
            "value_count#vc" : {
              "value" : 9
            }
          }
        }
      }
    }
    

    有什么想法吗?非常感谢。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Russ Cam    6 年前

    下面是一个工作示例

    private static void Main()
    {
        var defaultIndex = "topics";
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    
        var settings = new ConnectionSettings(pool)
            .DefaultIndex(defaultIndex);
    
        var client = new ElasticClient(settings);
    
        if (client.IndexExists(defaultIndex).Exists)
            client.DeleteIndex(defaultIndex);
    
        client.CreateIndex(defaultIndex, c => c
            .Mappings(m => m
                .Map<Topic>(mm => mm
                    .AutoMap()
                )
            )
        );
    
        var documents = Enumerable.Range(1, 10)
            .Select(i => new Topic
            {
                Status = i == 1 ? EnumStatus.Disabled : EnumStatus.Enabled,
                KeywordValues = Enumerable.Range(1, 5)
                    .Select(j => new KeywordValue
                    {
                        KeywordId = $"keyword {i} {j}"
                    }).ToList()
            });
    
        client.Bulk(b => b
            .IndexMany(documents, (d, document) => d
                .Document(document)
            )
            .Refresh(Refresh.WaitFor)
        );
    
        client.Search<Topic>(s => s
            .Size(0)
            .Query(q => +q
                .Term(t => t.Status, (int)EnumStatus.Enabled)
            )
            .Aggregations(ta => ta
                .Nested("kv", n => n.Path(p => p.KeywordValues)
                    .Aggregations(aa => aa
                        .ValueCount("vc", v => v.Field(vf => vf.KeywordValues.First().KeywordId))))
            )
        );
    }
    
    [ElasticsearchType(Name = "Topic")]
    public class Topic
    {
        [Number(NumberType.Integer, Coerce = true)]
        public EnumStatus Status { get; set; }
    
        [Nested]
        public List<KeywordValue> KeywordValues { get; set; }
    
    }
    
    [ElasticsearchType(Name = "KeywordValue")]
    public class KeywordValue
    {
        [Keyword]
        public string KeywordId { get; set; }
    }
    
    public enum EnumStatus
    {
        Enabled,
    
        Disabled
    }
    

    对搜索请求的响应为

    {
      "took" : 9,
      "timed_out" : false,
      "_shards" : {
        "total" : 5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : 9,
        "max_score" : 0.0,
        "hits" : [ ]
      },
      "aggregations" : {
        "nested#kv" : {
          "doc_count" : 45,
          "value_count#vc" : {
            "value" : 45
          }
        }
      }
    }