Dan Brown

Improved numeric term search capabilities

Prevented a quoted term also being added to fuzzy searches
and also added check to see if the term is numeric to check if
an exact match is required.

Closes #200
...@@ -160,26 +160,30 @@ class Entity extends Ownable ...@@ -160,26 +160,30 @@ class Entity extends Ownable
160 public function fullTextSearchQuery($fieldsToSearch, $terms, $wheres = []) 160 public function fullTextSearchQuery($fieldsToSearch, $terms, $wheres = [])
161 { 161 {
162 $exactTerms = []; 162 $exactTerms = [];
163 - if (count($terms) === 0) { 163 + $fuzzyTerms = [];
164 - $search = $this; 164 + $search = static::newQuery();
165 - $orderBy = 'updated_at'; 165 +
166 - } else {
167 foreach ($terms as $key => $term) { 166 foreach ($terms as $key => $term) {
168 $term = htmlentities($term, ENT_QUOTES); 167 $term = htmlentities($term, ENT_QUOTES);
169 $term = preg_replace('/[+\-><\(\)~*\"@]+/', ' ', $term); 168 $term = preg_replace('/[+\-><\(\)~*\"@]+/', ' ', $term);
170 - if (preg_match('/&quot;.*?&quot;/', $term)) { 169 + if (preg_match('/&quot;.*?&quot;/', $term) || is_numeric($term)) {
171 $term = str_replace('&quot;', '', $term); 170 $term = str_replace('&quot;', '', $term);
172 $exactTerms[] = '%' . $term . '%'; 171 $exactTerms[] = '%' . $term . '%';
173 - $term = '"' . $term . '"';
174 } else { 172 } else {
175 $term = '' . $term . '*'; 173 $term = '' . $term . '*';
174 + if ($term !== '*') $fuzzyTerms[] = $term;
176 } 175 }
177 - if ($term !== '*') $terms[$key] = $term;
178 } 176 }
179 - $termString = implode(' ', $terms); 177 +
178 + $isFuzzy = count($exactTerms) === 0 || count($fuzzyTerms) > 0;
179 +
180 + // Perform fulltext search if relevant terms exist.
181 + if ($isFuzzy) {
182 + $termString = implode(' ', $fuzzyTerms);
180 $fields = implode(',', $fieldsToSearch); 183 $fields = implode(',', $fieldsToSearch);
181 - $search = static::selectRaw('*, MATCH(name) AGAINST(? IN BOOLEAN MODE) AS title_relevance', [$termString]); 184 + $search = $search->selectRaw('*, MATCH(name) AGAINST(? IN BOOLEAN MODE) AS title_relevance', [$termString]);
182 $search = $search->whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termString]); 185 $search = $search->whereRaw('MATCH(' . $fields . ') AGAINST(? IN BOOLEAN MODE)', [$termString]);
186 + }
183 187
184 // Ensure at least one exact term matches if in search 188 // Ensure at least one exact term matches if in search
185 if (count($exactTerms) > 0) { 189 if (count($exactTerms) > 0) {
...@@ -191,13 +195,14 @@ class Entity extends Ownable ...@@ -191,13 +195,14 @@ class Entity extends Ownable
191 } 195 }
192 }); 196 });
193 } 197 }
194 - $orderBy = 'title_relevance'; 198 +
195 - }; 199 + $orderBy = $isFuzzy ? 'title_relevance' : 'updated_at';
196 200
197 // Add additional where terms 201 // Add additional where terms
198 foreach ($wheres as $whereTerm) { 202 foreach ($wheres as $whereTerm) {
199 $search->where($whereTerm[0], $whereTerm[1], $whereTerm[2]); 203 $search->where($whereTerm[0], $whereTerm[1], $whereTerm[2]);
200 } 204 }
205 +
201 // Load in relations 206 // Load in relations
202 if ($this->isA('page')) { 207 if ($this->isA('page')) {
203 $search = $search->with('book', 'chapter', 'createdBy', 'updatedBy'); 208 $search = $search->with('book', 'chapter', 'createdBy', 'updatedBy');
......