forked from elastic/search-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuildRequest.js
122 lines (109 loc) · 3.84 KB
/
buildRequest.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import buildRequestFilter from "./buildRequestFilter";
function buildFrom(current, resultsPerPage) {
if (!current || !resultsPerPage) return;
return (current - 1) * resultsPerPage;
}
function buildSort(sortDirection, sortField) {
if (sortDirection && sortField) {
return [{ [`${sortField}.keyword`]: sortDirection }];
}
}
function buildMatch(searchTerm) {
return searchTerm
? {
multi_match: {
query: searchTerm,
fields: ["title", "description"]
}
}
: { match_all: {} };
}
/*
Converts current application state to an Elasticsearch request.
When implementing an onSearch Handler in Search UI, the handler needs to take the
current state of the application and convert it to an API request.
For instance, there is a "current" property in the application state that you receive
in this handler. The "current" property represents the current page in pagination. This
method converts our "current" property to Elasticsearch's "from" parameter.
This "current" property is a "page" offset, while Elasticsearch's "from" parameter
is a "item" offset. In other words, for a set of 100 results and a page size
of 10, if our "current" value is "4", then the equivalent Elasticsearch "from" value
would be "40". This method does that conversion.
We then do similar things for searchTerm, filters, sort, etc.
*/
export default function buildRequest(state) {
const {
current,
filters,
resultsPerPage,
searchTerm,
sortDirection,
sortField
} = state;
const sort = buildSort(sortDirection, sortField);
const match = buildMatch(searchTerm);
const size = resultsPerPage;
const from = buildFrom(current, resultsPerPage);
const filter = buildRequestFilter(filters);
const body = {
// Static query Configuration
// --------------------------
// https://www.elastic.co/guide/en/elasticsearch/reference/7.x/search-request-highlighting.html
highlight: {
fragment_size: 200,
number_of_fragments: 1,
fields: {
title: {},
description: {}
}
},
//https://www.elastic.co/guide/en/elasticsearch/reference/7.x/search-request-source-filtering.html#search-request-source-filtering
_source: ["id", "nps_link", "title", "description"],
aggs: {
states: { terms: { field: "states.keyword", size: 30 } },
world_heritage_site: {
terms: { field: "world_heritage_site" }
},
visitors: {
range: {
field: "visitors",
ranges: [
{ from: 0.0, to: 10000.0, key: "0 - 10000" },
{ from: 10001.0, to: 100000.0, key: "10001 - 100000" },
{ from: 100001.0, to: 500000.0, key: "100001 - 500000" },
{ from: 500001.0, to: 1000000.0, key: "500001 - 1000000" },
{ from: 1000001.0, to: 5000000.0, key: "1000001 - 5000000" },
{ from: 5000001.0, to: 10000000.0, key: "5000001 - 10000000" },
{ from: 10000001.0, key: "10000001+" }
]
}
},
acres: {
range: {
field: "acres",
ranges: [
{ from: -1.0, key: "Any" },
{ from: 0.0, to: 1000.0, key: "Small" },
{ from: 1001.0, to: 100000.0, key: "Medium" },
{ from: 100001.0, key: "Large" }
]
}
}
},
// Dynamic values based on current Search UI state
// --------------------------
// https://www.elastic.co/guide/en/elasticsearch/reference/7.x/full-text-queries.html
query: {
bool: {
must: [match],
...(filter && { filter })
}
},
// https://www.elastic.co/guide/en/elasticsearch/reference/7.x/search-request-sort.html
...(sort && { sort }),
// https://www.elastic.co/guide/en/elasticsearch/reference/7.x/search-request-from-size.html
...(size && { size }),
...(from && { from })
};
return body;
}