Конструктор запросов с запросом соответствия префикса и запросом соответствия терминов в Elasti c Поиск не работает - PullRequest
0 голосов
/ 13 марта 2020

Я пытаюсь выполнить запрос ElasticSearch, который включает одно совпадение префикса для любого поля И запрос условий, который требует определенного значения в определенных полях. Запрос работал, когда это был просто запрос сопоставления префиксов. Добавление запроса условий как логического запроса не работает. Я получаю неописательную ошибку «переполнение стека». Почему? Я использую REST-клиент Elasti c для JAVA.

Вот мой код ...

    private SearchResultsAndFacets runQuery(
            List<String> colNames,
            int list_id,
            String query,
            List<String> filters,
            Integer offsetParam,
            Integer limitParam,
            String sort) throws IOException {

        int offset = 0; // more to do for implementing offset here

        RestHighLevelClient client = createHighLevelRestClient();
        int numberOfSearchHitsToReturn = 100; // defaults to 10

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.size(numberOfSearchHitsToReturn);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); // an optional timeout that controls how long the
        String[] includeFields = colNames.toArray(new String[colNames.size()]);
        String[] excludeFields = new String[] {}; // just need an exclude field in order to call
                                                    // fetchSource
        sourceBuilder.fetchSource(includeFields, excludeFields);
        sourceBuilder.from(offset);
        sourceBuilder.size(limitParam);

        for (String colName : colNames) {

            sourceBuilder.aggregation(AggregationBuilders.terms(colName)
                    .field(colName + ".keyword"));
        }

        MultiMatchQueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(query).type(Type.PHRASE_PREFIX);
//      sourceBuilder.query(queryBuilder);

        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("lastname", "SMITH");

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery().must(queryBuilder);

        for (String filter : filters) {
            int colonPos = filter.indexOf(':');
            if (colonPos == -1) {
                throw new BadRequestException("Bad filter: " + filter);
            }
            String column_name = filter.substring(0, colonPos);
            List<String> values;
            try {
                values = Util.getMapper().readValue(filter.substring(colonPos + 1), STRING_LIST_TYPE_REF);
            } catch (IOException e) {
                LoggerFactory.getLogger(SearchService.class).error("Bad filter", e);
                throw new BadRequestException("Bad filter: " + filter);
            }
            boolQueryBuilder.must(boolQueryBuilder.must(QueryBuilders.termsQuery(column_name, values)));
        }
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest("contacts_" + list_id).source(sourceBuilder);
        long start = System.currentTimeMillis();

        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = searchResponse.getHits().getHits();

        List<LinkedHashMap> rows = new ArrayList<LinkedHashMap>();
        for (SearchHit hit : hits) {
            Map<String, Object> contactMap = hit.getSourceAsMap();
            LinkedHashMap<String, Object> contactLHM = new LinkedHashMap<>(contactMap);
            rows.add((LinkedHashMap<String, Object>) contactLHM);
        }

        System.out.print(searchResponse);
        client.close();

        SearchResults sr = new SearchResults();
        sr.rows = rows;

        // integrate offset and limit into query.
        sr.totalRows = rows.size();
        sr.firstRow = offset + 1;
        sr.lastRow = sr.firstRow + rows.size();
        sr.elapsed = System.currentTimeMillis() - start;

        LinkedHashMap<String, ArrayList<Bucket>> facetsData = new LinkedHashMap<String, ArrayList<Bucket>>();
        SearchResultsAndFacets srf = new SearchResultsAndFacets();
        for (String colName : colNames) {
            Terms agg = searchResponse.getAggregations().get(colName);
            ArrayList<Bucket> buckets = new ArrayList<Bucket>();
            for (Terms.Bucket bucket : agg.getBuckets()) {
                String key = bucket.getKeyAsString();
                long docCount = bucket.getDocCount();
                Bucket fd = new Bucket(key, docCount);
                buckets.add(fd);
            }
            facetsData.put(colName, buckets);
        }
        srf.facetsData = facetsData;

        srf.searchResults = sr;

        return srf;

    }
...