Elasticsearch - 如何查找嵌套对象的字段值大于 X 且最大日期的所有文档

问题描述 投票:0回答:1

我有一些公司模型的文件。每个公司都有一些财务报告。它们被设计为 Elasticsearch 的“嵌套”对象。例如: [ { "id": 1, "financials": [ { "periodEndDate": "2022-06-30", "cash": 10000, "inventory": 24000 }, { "periodEndDate": "2022-12-31", "cash": 12000, "inventory": 19000 } ] }, { "id": 2, "financials": [ { "periodEndDate": "2022-12-31", "cash": 200000, "inventory": 1590000 }, { "periodEndDate": "2023-03-31", "cash": 210000, "inventory": 1430000 } ] } ]

我想找出在
最近期结束日期

报告中拥有现金> 200000的所有公司。期望的结果是公司 2,因为该公司最近的报告的 periodEndDate 为2023-03-31,报告的现金为 210000 如何编写查询?

另外,如果我想用

最近日期的第二个

来过滤报告,查询是什么? 我找到了这篇文章:

ElasticSearch - 获取字段值为 x 并且该类型的最大日期低于 y 日期的文档

但它需要“负”过滤器,这对我来说不起作用,因为财务报告嵌套对象有太多字段。

java elasticsearch nested
1个回答
0
投票
top_hits

bucket_selector
聚合的组合来完成。基本上,
top_hits
会找到最新的报告,
bucket_selector
会删除所有没有足够现金的公司。
PUT test
{
  "mappings": {
    "properties": {
      "id": {
        "type": "long"
      },
      "financials": {
        "type": "nested",
        "properties": {
          "periodEndDate": {
            "type": "date"
          },
          "cash": {
            "type":"long"
          },
          "inventory": {
            "type": "long"
          }
        }
      }
    }
  }
}

POST test/_bulk?refresh
{"index":{"_id":1}}
{"id":1,"financials":[{"periodEndDate":"2022-06-30","cash":10000,"inventory":24000},{"periodEndDate":"2022-12-31","cash":12000,"inventory":19000}]}
{"index":{"_id":2}}
{"id":2,"financials":[{"periodEndDate":"2022-12-31","cash":200000,"inventory":1590000},{"periodEndDate":"2023-03-31","cash":210000,"inventory":1430000}]}

POST test/_search
{
  "size": 0,
  "aggs": {
    "companies": {
      "terms": {
        "field": "id"
      },
      "aggs": {
        "nested": {
          "nested": {
            "path": "financials"
          },
          "aggs": {
            "last_cash": {
              "top_hits": {
                "sort": [
                  {
                    "financials.periodEndDate": {
                      "order": "desc"
                    }
                  }
                ],
                "_source": {
                  "includes": [
                    "financials.cash",
                    "financials.periodEndDate"
                  ]
                },
                "size": 1
              }
            }
          }
        },
        "having.top_cash": {
          "bucket_selector": {
            "buckets_path": {
              "last_cash": "nested>last_cash[_source.cash]"
            },
            "script": "params.last_cash > 200000"
          }
        }
      }
    }
  }
}

此方法有一些局限性,包括可扩展性差、可以处理的公司数量有限以及不支持第二旧的报告。如果您还需要按相关性对公司进行排序或翻页,那么这也不是最佳解决方案。

为了实现所有这些功能并构建可扩展的解决方案,我建议在索引期间添加额外的处理,并将最新报告和最新报告的第二个索引作为主对象中的专用字段,而不是将它们存储为嵌套并尝试在搜索时间内找到最新的和第二最新的。所以,基本上你的记录应该是这样的:

{ "id": 1, "latest_finanicals": { "periodEndDate": "2022-12-31", "cash": 12000, "inventory": 19000 } }, "previous_finanicals": { "periodEndDate": "2022-06-30", "cash": 10000, "inventory": 24000 } } "financials": [ { "periodEndDate": "2022-06-30", "cash": 10000, "inventory": 24000 }, { "periodEndDate": "2022-12-31", "cash": 12000, "inventory": 19000 } ] }

具有 
latest_finanicals

previous_finanicals
具有
object
类型而不是
nested
类型。那么你所有的查询都会变得非常简单。
    

© www.soinside.com 2019 - 2024. All rights reserved.