search method
Search :-)
Implementation
Future<SearchResult> search({
String? index,
String? type,
Map? query,
// TODO: investigate if/when this should be deprecated in favour of `from`
int? offset,
// TODO: investigate if/when this should be deprecated in favour of `size`
int? limit,
List<Object>? fields,
dynamic source,
Map? suggest,
List<Map>? sort,
Map? aggregations,
Duration? scroll,
HighlightOptions? highlight,
bool? trackTotalHits,
int? size,
double? minScore,
}) async {
final path = [
if (index != null) index,
if (type != null) type,
'_search',
];
final map = {
if (source != null) '_source': source,
if (fields != null) 'fields': fields,
'query': query ?? Query.matchAll(),
if (offset != null) 'from': offset,
if (limit != null) 'size': limit,
if (suggest != null) 'suggest': suggest,
if (sort != null) 'sort': sort,
if (aggregations != null) 'aggregations': aggregations,
if (highlight != null) 'highlight': highlight.toMap(),
if (trackTotalHits != null) 'track_total_hits': trackTotalHits,
if (size != null) 'size': size,
if (minScore != null) 'min_score': minScore,
};
final params = {
'search_type': 'dfs_query_then_fetch',
if (scroll != null) 'scroll': scroll.inSeconds.toString() + 's',
};
final rs = await _transport
.send(Request('POST', path, params: params, bodyMap: map));
rs.throwIfStatusNotOK(message: 'Failed to search $query.');
final body = rs.bodyAsMap;
final hitsMap = body['hits'] as Map<String, dynamic>? ?? const {};
final totalCount = _extractTotalCount(hitsMap);
final results = _extractDocList(hitsMap);
final suggestMap = body['suggest'] as Map? ?? const {};
final suggestEntries =
suggestMap.entries.where((e) => e.value != null).map((e) {
final list = (e.value as List).cast<Map>();
final hits = list.map((map) {
final optionsList = (map['options'] as List).cast<Map>();
final options = optionsList.map((m) {
return SuggestHitOption(
m['text'] as String,
m['score'] as double,
freq: (m['freq'] ?? -1) as int,
highlighted: m['highlighted'] as String,
);
}).toList();
return SuggestHit(
map['text'] as String,
map['offset'] as int,
map['length'] as int,
options,
);
}).toList();
return MapEntry('', hits);
});
final suggestHits = Map.fromEntries(suggestEntries);
final aggMap = body['aggregations'] as Map<String, dynamic>? ?? const {};
final aggResult = aggMap.map<String, Aggregation>((k, v) {
final agg = Aggregation(k, aggregations![k] as Map<String, dynamic>,
v as Map<String, dynamic>);
return MapEntry(k, agg);
});
return SearchResult(
totalCount,
results,
suggestHits: suggestHits.isEmpty ? null : suggestHits,
aggregations: aggResult.isEmpty ? null : aggResult,
scrollId: body['_scroll_id'] as String?,
);
}