【问题标题】:Elasticsearch query on array of objects with date带有日期的对象数组的 Elasticsearch 查询
【发布时间】:2021-04-16 12:44:48
【问题描述】:

您好,我是 Elasticsearch 的新手,正在尝试使用 spring-data-elasticsearch 实施解决方案。我的索引数据如下所示:

[
  {
    "worker": "A",
    "availability": [
      {
        "startDate": "2020-01-12",
        "endDate": "2020-02-12"
      },
      {
        "startDate": "2020-04-12",
        "endDate": "2020-05-12"
      }
    ]
  },
  {
    "worker": "B",
    "availability": [
      {
        "startDate": "2020-04-12",
        "endDate": "2020-11-12"
      }
    ]
  }
]

通过引用我计划使用范围查询来获取指定日期范围内的记录的弹性文档,例如,我想获取“2020-05-12 到 2020-06-12”之间的可用工作人员。这是我形成的查询:

{
    "query": {
        "bool": {
            "must": [
                {
                    "nested": {
                        "query": {
                            "range": {
                                "availability.start_date": {
                                    "from": "2020-05-12T00:00:00.000Z",
                                    "to": "2020-06-12T00:00:00.000Z",
                                    "include_lower": true,
                                    "include_upper": true,
                                    "boost": 1.0
                                }
                            }
                        },
                        "path": "availability",
                        "ignore_unmapped": false,
                        "score_mode": "none",
                        "boost": 1.0
                    }
                }
            ],
            "adjust_pure_negative": true,
            "boost": 1.0
        }
    }
}

上面的查询在执行时显示空命中,但是当我使用索引的日期时,我能够获取记录(例如,如果我将日期指定为“2020-04-12 到 2020-11-12 " 显示工人 B 结果)。根据范围查询,如果我没记错的话,它也应该适用于我之前的案例。我遵循的方法有什么问题吗?请指教。

【问题讨论】:

    标签: spring-boot elasticsearch spring-data-elasticsearch elasticsearch-aggregation elasticsearch-dsl


    【解决方案1】:

    您没有其start_date (!!) 介于2020-05-122020-06-12 之间的工人。我认为你需要为你想要达到的目标采取不同的方式。

    由于您尝试在范围上进行匹配,因此利用 date_range field type 可能会更容易。您的映射应如下所示:

    PUT your-index
    {
      "mappings": {
        "properties": {
          "availability": {
            "type": "date_range", 
            "format": "yyyy-MM-dd"
          }
        }
      }
    }
    

    然后您可以像这样索引您的所有工作人员的可用性:

    {
      "worker": "A",
      "availability": [
        {
          "gte": "2020-01-12",
          "lte": "2020-02-12"
        },
        {
          "gte": "2020-04-12",
          "lte": "2020-05-12"
        }
      ]
    }
    {
      "worker": "B",
      "availability": [
        {
          "gte": "2020-04-12",
          "lte": "2020-11-12"
        }
      ]
    }
    

    然后你可以像这样执行你想要的搜索:

    {
      "query": {
        "range": {
          "availability": {
            "gte": "2020-05-12",
            "lte": "2020-06-12",
            "relation": "contains"
          }
        }
      }
    }
    

    你会发现只有工人 B 满足条件。

    更新

    您在 Java 中的查询需要是这样的:

        final BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
    
        queryBuilder.must(QueryBuilders.matchQuery("name", "A"));
    
        RangeQueryBuilder availability = QueryBuilders.rangeQuery("availability")
               .gte(query.getStartDate())
               .lte(query.getEndDate());
    
        queryBuilder.must(availability);
    
        Pageable pageable = PageRequest.of(pageNumber, pageSize);
    
        // @formatter:off
        return new NativeSearchQueryBuilder()
                .withPageable(pageable)
                .withQuery(queryBuilder)
                .build();
    

    【讨论】:

    • 为此点赞!!! this 应该是 FieldType.Date_Range 类型,你不需要类 Availability,它应该只是一个带有 gtelte 键的 Map
    • 你得到的错误是因为availability实际上应该是List<Map<String, String>>List<Map<String, Date>>
    • 太棒了!正如我之前评论的那样,您的查询不正确。我已经更新了我的答案,以向您展示正确的方法。
    • 太棒了,很高兴它成功了!是的,您需要恢复您的 Availability 对象并将日期范围与新的 partial 字段一起移动到那里。它将成为一个复合对象,您需要将availability 字段设为nested
    • 只有private Map<String, LocalDate> dates;Availability 内,因为在工人级别,您已经有一个Availability 列表
    猜你喜欢
    • 2015-12-10
    • 2021-04-17
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    • 2015-09-19
    • 2021-06-23
    • 1970-01-01
    • 2021-07-04
    相关资源
    最近更新 更多