如何执行搜索条件,例如elasticsearch列表中的where value?

How to perform an search condition like where value in a list in elastic search?

您好,我有一个名为 mep-reports-today 的弹性搜索索引。下面显示了它的外观。

{
  "took": 19,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 100,
    "max_score": 1.0,
    "hits": [
      {
        "_index": "mep-reports-today",
        "_type": "doc",
        "_id": "Rta62G0Bc1ykGt-JpwfK",
        "_score": 1.0,
        "_source": {
          "inventory": "SMS",
          "msg_text": "This is random text",
          "status": "ENROUTE",
          "@timestamp": "2019-09-09T15:47:48.778Z",
          "o_error": "",
          "flight_id": "92348fa1-ca6c-456a-b3b2-85fba2d2deed",
          "recipient": "420736408283",
          "account_id": "a56f7e14-20f9-40e6-90c6-10604140ac5f",
          "sender": "8800111",
          "campaign_id": "6f2abca3-b46d-43f3-91be-3278a8dd7dc0",
          "nof_segments": 1,
          "@version": 1,
          "submission_ts": 1568105380000,
          "delivery_ts": 1567491477000,
          "campaign_name": "Munchies Ireland Sandwitch and drinks promotion",
          "flight_name": "Very Very long long flight"
        }
      },
      {
        "_index": "mep-reports-today",
        "_type": "doc",
        "_id": "SNa62G0Bc1ykGt-JpwfL",
        "_score": 1.0,
        "_source": {
          "inventory": "MMS",
          "msg_text": "This is random text",
          "status": "ENROUTE",
          "@timestamp": "2019-09-01T02:40:42.040Z",
          "o_error": "",
          "flight_id": "92348fa1-ca6c-456a-b3b2-85fba2d2deed",
          "recipient": "420736408281",
          "account_id": "a56f7e14-20f9-40e6-90c6-10604140ac5f",
          "sender": "8800111",
          "campaign_id": "6f2abca3-b46d-43f3-91be-3278a8dd7dc0",
          "nof_segments": 1,
          "@version": 1,
          "submission_ts": 1568105380000,
          "delivery_ts": 1565902976000,
          "campaign_name": "Starbucks Promotion",
          "flight_name": "Short Flight"
        }
      },
      {
        "_index": "mep-reports-today",
        "_type": "doc",
        "_id": "Sda62G0Bc1ykGt-JpwfL",
        "_score": 1.0,
        "_source": {
          "inventory": "SMS",
          "msg_text": "This is random text",
          "status": "ENROUTE",
          "@timestamp": "2019-09-01T16:00:05.666Z",
          "o_error": "",
          "flight_id": "92348fa1-ca6c-456a-b3b2-85fba2d2deed",
          "recipient": "420736408281",
          "account_id": "a56f7e14-20f9-40e6-90c6-10604140ac5f",
          "sender": "8800111",
          "campaign_id": "6f2abca3-b46d-43f3-91be-3278a8dd7dc0",
          "nof_segments": 1,
          "@version": 1,
          "submission_ts": 1568105380000,
          "delivery_ts": 1558893228000,
          "campaign_name": "Starbucks Promotion",
          "flight_name": "Very Very long long flight"
        }
      },
      {
        "_index": "mep-reports-today",
        "_type": "doc",
        "_id": "Sta62G0Bc1ykGt-JpwfL",
        "_score": 1.0,
        "_source": {
          "inventory": "SMS",
          "msg_text": "This is random text",
          "status": "ENROUTE",
          "@timestamp": "2019-09-03T17:09:50.380Z",
          "o_error": "",
          "flight_id": "92348fa1-ca6c-456a-b3b2-85fba2d2deed",
          "recipient": "420736408281",
          "account_id": "a56f7e14-20f9-40e6-90c6-10604140ac5f",
          "sender": "8800111",
          "campaign_id": "6f2abca3-b46d-43f3-91be-3278a8dd7dc0",
          "nof_segments": 1,
          "@version": 1,
          "submission_ts": 1568105380000,
          "delivery_ts": 1547471597000,
          "campaign_name": "Munchies Ireland Sandwitch and drinks promotion",
          "flight_name": "Very Very long long flight"
        }
      },
      {
        "_index": "mep-reports-today",
        "_type": "doc",
        "_id": "Tta62G0Bc1ykGt-JpwfL",
        "_score": 1.0,
        "_source": {
          "inventory": "SMS",
          "msg_text": "This is random text",
          "status": "ENROUTE",
          "@timestamp": "2019-09-09T21:46:14.947Z",
          "o_error": "",
          "flight_id": "92348fa1-ca6c-456a-b3b2-85fba2d2deed",
          "recipient": "420736408283",
          "account_id": "a56f7e14-20f9-40e6-90c6-10604140ac5f",
          "sender": "8800111",
          "campaign_id": "6f2abca3-b46d-43f3-91be-3278a8dd7dc0",
          "nof_segments": 1,
          "@version": 1,
          "submission_ts": 1568105380000,
          "delivery_ts": 1559378049000,
          "campaign_name": "Munchies Ireland Sandwitch and drinks promotion",
          "flight_name": "Short Flight"
        }
      }
    ]
  }
}

我有一个搜索屏幕,用户可以在其中搜索不同的字段,例如 @timestamp、status、campaign_id、recipient、inventory、flight_id、account_id。我正在使用 java 弹性搜索客户端向弹性搜索发出搜索请求。但是,当我需要搜索状态和库存字段时,它没有按预期工作。状态和清单作为多个 select 选项提供给用户。

下面是我构建查询的方式。

@存储库 public class MessageHistoryReportingRepository {

public MessageHistorySearchResponse findAll(MessageHistoryFilterRequest messageHistoryFilterRequest) {

        SearchRequestBuilder searchRequestBuilder = new SearchRequestBuilder(ELASTIC_SEARCH_INDEX);

        SearchRequest searchRequest = searchRequestBuilder.from(messageHistoryFilterRequest.getPageNumber())
                .size(messageHistoryFilterRequest.getPageSize()).timeout(300, TimeUnit.SECONDS)
                .range(messageHistoryFilterRequest.getStartDate(), messageHistoryFilterRequest.getEndDate())
                .msisdn(messageHistoryFilterRequest.getMsisdn()).accountId(messageHistoryFilterRequest.getAccountId())
                .campaignId(messageHistoryFilterRequest.getCampaignId())
                .flightId(messageHistoryFilterRequest.getFlightId())
                .cdrStatus(messageHistoryFilterRequest.getCdrStatus())
                .inventoryCode(messageHistoryFilterRequest.getInventoryCode()).sort().build();

        SearchResponse searchResponse = null;
        List<MessageHistory> messageHistories = null;
        try {
            searchResponse = elasticSearchClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits searchHits = searchResponse.getHits();
            List<SearchHit> searchHitResults = Arrays.asList(searchHits.getHits());
            messageHistories = searchHitResults.stream().map(this::translate).collect(Collectors.toList());
            return new MessageHistorySearchResponse(messageHistories, messageHistoryFilterRequest.getPageSize(),
                    messageHistoryFilterRequest.getPageNumber(), searchHits.getTotalHits());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

static class SearchRequestBuilder {

        private SearchRequest searchRequest;

        private SearchSourceBuilder searchSourceBuilder;

        private BoolQueryBuilder boolQueryBuilder;

        SearchRequestBuilder(String elasticSearchIndex) {
            this.searchRequest = new SearchRequest(elasticSearchIndex);
            this.searchRequest.indicesOptions(IndicesOptions.lenientExpandOpen());
            this.searchSourceBuilder = new SearchSourceBuilder();
            this.searchRequest.source(searchSourceBuilder);
            this.boolQueryBuilder = QueryBuilders.boolQuery();
            this.searchSourceBuilder.query(this.boolQueryBuilder);
        }

        SearchRequestBuilder from(Integer pageNumber) {
            this.searchSourceBuilder.from(pageNumber);
            return this;
        }

        SearchRequestBuilder size(Integer pageSize) {
            this.searchSourceBuilder.size(pageSize);
            return this;
        }

        SearchRequestBuilder timeout(long duration, TimeUnit timeUnit) {
            this.searchSourceBuilder.timeout(new TimeValue(duration, TimeUnit.SECONDS));
            return this;
        }

        SearchRequestBuilder range(ZonedDateTime startDate, ZonedDateTime endDate) {

            RangeQueryBuilder startRangeQueryBuilder = QueryBuilders.rangeQuery("@timestamp").gte(startDate);
            startRangeQueryBuilder.format("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

            boolQueryBuilder.must(startRangeQueryBuilder);

            RangeQueryBuilder endRangeQueryBuilder = QueryBuilders.rangeQuery("@timestamp").lte(endDate.plusDays(1l));
            boolQueryBuilder.must(endRangeQueryBuilder);
            endRangeQueryBuilder.format("yyyy-MM-dd'T'HH:mm:ss.SSSZ");

            return this;
        }

        SearchRequestBuilder msisdn(String msisdn) {
            if (msisdn != null) {
                if (msisdn.indexOf("*") >= 0) {
                    WildcardQueryBuilder msisdnWildCardQueryBuilder = new WildcardQueryBuilder("recipient", msisdn);
                    boolQueryBuilder.must(msisdnWildCardQueryBuilder);
                } else {
                    MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("recipient", msisdn);
                    boolQueryBuilder.must(matchQueryBuilder);
                }
            }
            return this;
        }

        SearchRequestBuilder accountId(UUID accountId) {
            if (accountId != null) {
                MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("account_id", accountId.toString());
                boolQueryBuilder.must(matchQueryBuilder);
            }
            return this;
        }

        SearchRequestBuilder campaignId(UUID campaignId) {
            if (campaignId != null) {
                MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("campaign_id", campaignId.toString());
                boolQueryBuilder.must(matchQueryBuilder);
            }
            return this;
        }

        SearchRequestBuilder flightId(UUID flightId) {
            if (flightId != null) {
                MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("flight_id", flightId.toString());
                boolQueryBuilder.must(matchQueryBuilder);
            }
            return this;
        }

        SearchRequestBuilder cdrStatus(List<String> cdrStatus) {
            if (cdrStatus != null && cdrStatus.size() > 0) {
                for(String cdrStatusCode:cdrStatus) {
                    MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("status", cdrStatusCode);
                    boolQueryBuilder.should(matchQueryBuilder);
                }
            }
            return this;
        }

        SearchRequestBuilder inventoryCode(List<String> inventoryCode) {

            if (inventoryCode != null && inventoryCode.size() > 0) {
                for(String inventoryCodeValue:inventoryCode) {
                    MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("inventory", inventoryCodeValue);
                    boolQueryBuilder.should(matchQueryBuilder);
                }
            }

//          if (inventoryCode != null) {
//              MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("inventory", inventoryCode);
//              boolQueryBuilder.must(matchQueryBuilder);
//          }
            return this;
        }

        SearchRequestBuilder sort() {
            searchSourceBuilder.sort(new FieldSortBuilder("@timestamp").order(SortOrder.DESC));
            return this;
        }

        SearchRequestBuilder scroll(TimeValue value) {
            searchRequest.scroll(new Scroll(value));
            return this;
        }

        SearchRequestBuilder fetchSourceContext(boolean fetchSource, String[] includes, String[] excludes) {
            FetchSourceContext fetchContext = new FetchSourceContext(fetchSource, includes, excludes);
            this.searchSourceBuilder.fetchSource(fetchContext);
            return this;
        }

        SearchRequest build() {
            return this.searchRequest;
        }

    }
}

我想要实现的是根据下面提到的用户输入来做和设置条件。

@timestamp > (input start date ) and @timestamp < (input end date) and campaign_id = 6f2abca3-b46d-43f3-91be-3278a8dd7dc0 and recipient = "420736408283" and inventory in ( 'SMS', 'MMS') and status in ( 'ENROUTE' , 'DELIVERED'). 

但是它不起作用,因为库存和状态字段有多个 select。知道如何重写我的 SearchRequestBuilder class.

SearchRequestBuilder cdrStatus(List<String> cdrStatus) {
                if (cdrStatus != null && cdrStatus.size() > 0) {
                    for(String cdrStatusCode:cdrStatus) {
                        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("status", cdrStatusCode);
                        boolQueryBuilder.should(matchQueryBuilder);
                    }
                }
                return this;
            }

            SearchRequestBuilder inventoryCode(List<String> inventoryCode) {

                if (inventoryCode != null && inventoryCode.size() > 0) {
                    for(String inventoryCodeValue:inventoryCode) {
                        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("inventory", inventoryCodeValue);
                        boolQueryBuilder.should(matchQueryBuilder);
                    }
                }

    //          if (inventoryCode != null) {
    //              MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("inventory", inventoryCode);
    //              boolQueryBuilder.must(matchQueryBuilder);
    //          }
                return this;
            }

非常感谢

替换这个

for(String inventoryCodeValue:inventoryCode) {
                        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("inventory", inventoryCodeValue);
                        boolQueryBuilder.should(matchQueryBuilder);
                    }

有了这个,

TermsQueryBuilder termsQueryBuilder = new TermsQueryBuilder("inventory",inventoryCode);
boolQueryBuilder.should(termsQueryBuilder);

类似的变化适用于 cdrStatus