Я пытаюсь выполнить запрос 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;
}