开发者社区> 问答> 正文

ElasticSearch 7.13.2 版本中过滤嵌套数据满足条件的文档

我有一个索引,存储的是每个货物在每个仓库中的出入库流水信息,mapping如下: { "mappings": { "properties": { // 出入库流水信息 "details": { "type": "nested", "properties": { // 出入库流水审核时间 "auditDate": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }, // 审核后库存 "closingStock": { "type": "integer" }, // 审核前库存 "openingStock": { "type": "integer" }, // 出入库数量 "quantity": { "type": "integer" } } }, "id": { "type": "keyword" }, // 存货编码 "inventoryCode": { "type": "keyword" }, "lastAuditDate": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }, "lastClosingStock": { "type": "integer" }, // 仓库ID "warehouseId": { "type": "long" } } } }

我想过滤出,满足某个日期前的最后一条出入库流水的期末库存数量大于0的文档,我想使用script进行出入库流水轮询时,结果doc并不包含嵌套类型的数据:

GET bec_erp_warehouse_stock/_search { "query": { "bool": { "filter": [ { "script": { "script": { "source": """ def details = doc['details']; if (details.size() > 0) { def lastDetail = details[details.size() - 1]; return lastDetail['closingStock'].value > 0; } return false; """ } } } ] } } }

"failed_shards" : [ { "shard" : 0, "index" : "bec_erp_warehouse_stock_1646793913013456898", "node" : "tzYpyrZHQJuBSJLJ0BZHXw", "reason" : { "type" : "script_exception", "reason" : "runtime error", "script_stack" : [ "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:65)", "org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:27)", "details = doc['details'];\n ", " ^---- HERE" ], "script" : " ...", "lang" : "painless", "position" : { "offset" : 35, "start" : 21, "end" : 63 }, "caused_by" : { "type" : "illegal_argument_exception", "reason" : "No field found for [details] in mapping" } } } ]

请问还有什么其他方式能够实现我的期望吗?

展开
收起
1753431467106869 2023-04-18 15:06:18 212 0
1 条回答
写回答
取消 提交回答
  • 滤出满足某个日期前的最后一条出入库流水的期末库存数量大于0的文档,你可以使用nested query和nested sort来实现。nested query可以让你查询嵌套类型的字段,nested sort可以让你按照嵌套类型的字段进行排序。具体的语法如下:

    GET bec_erp_warehouse_stock/_search
    {
    "query": {
    "bool": {
    "filter": [
    {
    "nested": {
    "path": "details",
    "query": {
    "range": {
    "details.auditDate": {
    "lte": "2021-11-01" // 你想要的日期
    }
    }
    }
    }
    },
    {
    "script": {
    "script": {
    "source": """
    def details = params._source.details;
    if (details.size() > 0) {
    def lastDetail = details[details.size() - 1];
    return lastDetail.closingStock > 0;
    }
    return false;
    """
    }
    }
    }
    ]
    }
    },
    "sort": [
    {
    "details.auditDate": {
    "order": "desc",
    "nested": {
    "path": "details",
    "filter": {
    "range": {
    "details.auditDate": {
    "lte": "2021-11-01" // 同上
    }
    }
    }
    }
    }
    }
    ]
    }

    这个查询语句的意思是,先用nested query过滤出所有details中auditDate小于等于某个日期的文档,然后用script过滤出这些文档中最后一条流水的closingStock大于0的文档,最后用nested sort按照最后一条流水的auditDate降序排序。

    2023-10-09 09:16:14
    赞同 1 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
阿里云Elasticsearch体系架构与特性解析 立即下载
开源与云:Elasticsearch应用剖析 立即下载
《Elasticsearch全观测解决方案》 立即下载