별도의 쿼리를 하나의 쿼리로 병합

Nov 30 2020

boolQueryBuilder를 사용하여 status1 또는 status2를 확인하고 시간이 currentTime보다 작은 지 확인하는 다음 쿼리가 있습니다.

 public BoolQueryBuilder createSearchQuery(Long currentTime) {
        // Build and operator
        final BoolQueryBuilder firstAndOperator = createAndOperator(currentTime, "status1");

        // Build AND operator 
        final BoolQueryBuilder secondAndOperator = createAndOperator(currentTime, "status2);

        // Build OR
        return createOrOperator(firstAndOperator, secondAndOperator);
    }

    private BoolQueryBuilder createOrOperator(BoolQueryBuilder firstAndOperator, BoolQueryBuilder secondAndOperator) {
        return new BoolQueryBuilder()
            .should(firstAndOperator)
            .should(secondAndOperator);
    }

    private BoolQueryBuilder createAndOperator(Long currentDate, Status status) {
        return QueryBuilders.boolQuery()
            .must(QueryBuilders.matchQuery(STATUS, status))
            .must(QueryBuilders.rangeQuery(TIME).lte(currentDate));
    }

multiMatchQuery를 사용하여 병합하는 방법?

이것은 내 시도이지만 작동하지 않습니다

 public BoolQueryBuilder createSearchQuery(Long currentTime) {
        return new BoolQueryBuilder()
            .should(QueryBuilders
                .multiMatchQuery("status1" + " " + "status2", STATUS)
                .type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX)
                .operator(Operator.OR))
            .must(QueryBuilders.rangeQuery(TIME)
                .lte(currentTime));
    }

답변

Val Nov 30 2020 at 16:53

나는 귀하의 multi_match쿼리가 잘못되었다고 생각하며 filter대신 사용해야 합니다 must. 따라서 대신 다음과 같아야합니다.

public BoolQueryBuilder createSearchQuery(Long currentTime) {
    return new BoolQueryBuilder()
        .should(QueryBuilders
            .multiMatchQuery(STATUS, "status1", "status2")
            .operator(Operator.OR))
        .filter(QueryBuilders.rangeQuery(TIME)
            .lte(currentTime));

그러나 나는 multi_match그 목적으로 사용하지 않고 대신 두 개의 term필터를 활용 합니다.

public BoolQueryBuilder createSearchQuery(Long currentTime) {
    return new BoolQueryBuilder()
        .minimumShouldMatch(1)
        .should(QueryBuilders.matchQuery("status1", STATUS))
        .should(QueryBuilders.matchQuery("status2", STATUS))
        .filter(QueryBuilders.rangeQuery(TIME)
            .lte(currentTime));