1 | 'use strict';
|
2 |
|
3 | const _ = require('lodash');
|
4 | const Query = require('./Query');
|
5 |
|
6 | function createAddressShould(vs) {
|
7 | const should = {
|
8 | bool: {
|
9 | _name: 'fallback.address',
|
10 | must: [
|
11 | {
|
12 | match_phrase: {
|
13 | 'address_parts.number': {
|
14 | query: vs.var('input:housenumber')
|
15 | }
|
16 | }
|
17 | },
|
18 | {
|
19 | match_phrase: {
|
20 | 'address_parts.street': {
|
21 | query: vs.var('input:street')
|
22 | }
|
23 | }
|
24 | }
|
25 | ],
|
26 | filter: {
|
27 | term: {
|
28 | layer: 'address'
|
29 | }
|
30 | }
|
31 | }
|
32 | };
|
33 |
|
34 | if (vs.isset('boost:address')) {
|
35 | should.bool.boost = vs.var('boost:address');
|
36 | }
|
37 |
|
38 | return should;
|
39 | }
|
40 |
|
41 | function createUnitAndAddressShould(vs) {
|
42 | const should = {
|
43 | bool: {
|
44 | _name: 'fallback.address',
|
45 | must: [
|
46 | {
|
47 | match_phrase: {
|
48 | 'address_parts.unit': {
|
49 | query: vs.var('input:unit')
|
50 | }
|
51 | }
|
52 | },
|
53 | {
|
54 | match_phrase: {
|
55 | 'address_parts.number': {
|
56 | query: vs.var('input:housenumber')
|
57 | }
|
58 | }
|
59 | },
|
60 | {
|
61 | match_phrase: {
|
62 | 'address_parts.street': {
|
63 | query: vs.var('input:street')
|
64 | }
|
65 | }
|
66 | }
|
67 | ],
|
68 | filter: {
|
69 | term: {
|
70 | layer: 'address'
|
71 | }
|
72 | }
|
73 | }
|
74 | };
|
75 |
|
76 | if (vs.isset('boost:address')) {
|
77 | should.bool.boost = vs.var('boost:address');
|
78 | }
|
79 |
|
80 | return should;
|
81 | }
|
82 |
|
83 | function createPostcodeAndAddressShould(vs) {
|
84 | const should = {
|
85 | bool: {
|
86 | _name: 'fallback.address',
|
87 | must: [
|
88 | {
|
89 | match_phrase: {
|
90 | 'address_parts.zip': {
|
91 | query: vs.var('input:postcode')
|
92 | }
|
93 | }
|
94 | },
|
95 | {
|
96 | match_phrase: {
|
97 | 'address_parts.number': {
|
98 | query: vs.var('input:housenumber')
|
99 | }
|
100 | }
|
101 | },
|
102 | {
|
103 | match_phrase: {
|
104 | 'address_parts.street': {
|
105 | query: vs.var('input:street')
|
106 | }
|
107 | }
|
108 | }
|
109 | ],
|
110 | filter: {
|
111 | term: {
|
112 | layer: 'address'
|
113 | }
|
114 | }
|
115 | }
|
116 | };
|
117 |
|
118 | if (vs.isset('boost:address')) {
|
119 | should.bool.boost = vs.var('boost:address');
|
120 | }
|
121 |
|
122 | return should;
|
123 | }
|
124 |
|
125 | function createStreetShould(vs) {
|
126 | const should = {
|
127 | bool: {
|
128 | _name: 'fallback.street',
|
129 | must: [
|
130 | {
|
131 | match_phrase: {
|
132 | 'address_parts.street': {
|
133 | query: vs.var('input:street')
|
134 | }
|
135 | }
|
136 | }
|
137 | ],
|
138 | filter: {
|
139 | term: {
|
140 | layer: 'street'
|
141 | }
|
142 | }
|
143 | }
|
144 | };
|
145 |
|
146 | if (vs.isset('boost:street')) {
|
147 | should.bool.boost = vs.var('boost:street');
|
148 | }
|
149 |
|
150 | return should;
|
151 |
|
152 | }
|
153 |
|
154 | function createLayerIdsShould(layer, ids) {
|
155 |
|
156 |
|
157 | return _.set({}, ['terms', `parent.${layer}_id`], ids);
|
158 | }
|
159 |
|
160 | class AddressesUsingIdsQuery extends Query {
|
161 | constructor() {
|
162 | super();
|
163 | }
|
164 |
|
165 | render(vs) {
|
166 |
|
167 | const base = {
|
168 | query: {
|
169 | function_score: {
|
170 | query: {
|
171 | bool: {
|
172 | minimum_should_match: 1,
|
173 | should: [
|
174 | createStreetShould(vs)
|
175 | ]
|
176 | }
|
177 | }
|
178 | }
|
179 | },
|
180 | size: vs.var('size'),
|
181 | track_scores: vs.var('track_scores')
|
182 | };
|
183 |
|
184 |
|
185 | if (vs.isset('input:housenumber') && vs.isset('input:postcode')) {
|
186 | base.query.function_score.query.bool.should.push(createPostcodeAndAddressShould(vs));
|
187 | }
|
188 |
|
189 | if (vs.isset('input:housenumber') && vs.isset('input:unit')) {
|
190 | base.query.function_score.query.bool.should.push(createUnitAndAddressShould(vs));
|
191 | }
|
192 | else if (vs.isset('input:housenumber')) {
|
193 | base.query.function_score.query.bool.should.push(createAddressShould(vs));
|
194 | }
|
195 |
|
196 |
|
197 | if (vs.isset('input:layers')) {
|
198 |
|
199 | const layers_to_ids = vs.var('input:layers').$;
|
200 |
|
201 |
|
202 |
|
203 |
|
204 |
|
205 |
|
206 |
|
207 |
|
208 |
|
209 |
|
210 |
|
211 |
|
212 | const id_filters = Object.keys(layers_to_ids).reduce((acc, layer) => {
|
213 | if (!_.isEmpty(layers_to_ids[layer])) {
|
214 | acc.push(createLayerIdsShould(layer, layers_to_ids[layer]));
|
215 | }
|
216 | return acc;
|
217 | }, []);
|
218 |
|
219 |
|
220 |
|
221 | _.set(base.query.function_score.query.bool, 'filter.bool', {
|
222 | minimum_should_match: 1,
|
223 | should: id_filters
|
224 | });
|
225 |
|
226 | }
|
227 |
|
228 |
|
229 | if (!_.isEmpty(this._score)) {
|
230 | base.query.function_score.functions = _.compact(this._score.map(view => view(vs)));
|
231 | }
|
232 |
|
233 |
|
234 | if (!_.isEmpty(this._filter)) {
|
235 |
|
236 |
|
237 |
|
238 | _.set(
|
239 | base.query.function_score.query.bool,
|
240 | 'filter.bool.must',
|
241 | _.compact(this._filter.map(view => view(vs))));
|
242 |
|
243 | }
|
244 |
|
245 | return base;
|
246 | }
|
247 |
|
248 | }
|
249 |
|
250 | module.exports = AddressesUsingIdsQuery;
|