88use Laravel \Scout \Builder ;
99use Laravel \Scout \Engines \Engine ;
1010use TeamTNT \TNTSearch \Exceptions \IndexNotFoundException ;
11+ use TeamTNT \TNTSearch \TNTGeoSearch ;
1112use TeamTNT \TNTSearch \TNTSearch ;
1213
1314class TNTSearchEngine extends Engine
@@ -17,6 +18,11 @@ class TNTSearchEngine extends Engine
1718 */
1819 protected $ tnt ;
1920
21+ /**
22+ * @var TNTGeoSearch
23+ */
24+ protected $ geotnt ;
25+
2026 /**
2127 * @var Builder
2228 */
@@ -26,10 +32,12 @@ class TNTSearchEngine extends Engine
2632 * Create a new engine instance.
2733 *
2834 * @param TNTSearch $tnt
35+ * @param TNTGeoSearch|null $geotnt
2936 */
30- public function __construct (TNTSearch $ tnt )
37+ public function __construct (TNTSearch $ tnt, TNTGeoSearch $ geotnt = null )
3138 {
3239 $ this ->tnt = $ tnt ;
40+ $ this ->geotnt = $ geotnt ;
3341 }
3442
3543 /**
@@ -46,21 +54,51 @@ public function update($models)
4654 $ index = $ this ->tnt ->getIndex ();
4755 $ index ->setPrimaryKey ($ models ->first ()->getKeyName ());
4856
57+ $ geoindex = null ;
58+ if ($ this ->geotnt ) {
59+ $ this ->geotnt ->selectIndex ("{$ models ->first ()->searchableAs ()}.geoindex " );
60+ $ geoindex = $ this ->geotnt ->getIndex ();
61+ $ geoindex ->loadConfig ($ this ->geotnt ->config );
62+ $ geoindex ->setPrimaryKey ($ models ->first ()->getKeyName ());
63+ $ geoindex ->indexBeginTransaction ();
64+ }
65+
4966 $ index ->indexBeginTransaction ();
50- $ models ->each (function ($ model ) use ($ index ) {
67+ $ models ->each (function ($ model ) use ($ index, $ geoindex ) {
5168 $ array = $ model ->toSearchableArray ();
5269
5370 if (empty ($ array )) {
5471 return ;
5572 }
5673
74+ if ($ geoindex ) {
75+ $ latitude = isset ($ array ['latitude ' ]) ? (float ) $ array ['latitude ' ] : null ;
76+ $ longitude = isset ($ array ['longitude ' ]) ? (float ) $ array ['longitude ' ] : null ;
77+ unset($ array ['longitude ' ]);
78+ unset($ array ['latitude ' ]);
79+ }
80+
5781 if ($ model ->getKey ()) {
5882 $ index ->update ($ model ->getKey (), $ array );
83+ if ($ geoindex ) {
84+ $ geoindex ->prepareAndExecuteStatement (
85+ 'DELETE FROM locations WHERE doc_id = :documentId; ' ,
86+ [['key ' => ':documentId ' , 'value ' => $ model ->getKey ()]]
87+ );
88+ }
5989 } else {
6090 $ index ->insert ($ array );
6191 }
92+ if ($ geoindex && !empty ($ latitude ) && !empty ($ longitude )) {
93+ $ array ['latitude ' ] = $ latitude ;
94+ $ array ['longitude ' ] = $ longitude ;
95+ $ geoindex ->insert ($ array );
96+ }
6297 });
6398 $ index ->indexEndTransaction ();
99+ if ($ this ->geotnt ) {
100+ $ geoindex ->indexEndTransaction ();
101+ }
64102 }
65103
66104 /**
@@ -78,6 +116,17 @@ public function delete($models)
78116 $ index = $ this ->tnt ->getIndex ();
79117 $ index ->setPrimaryKey ($ model ->getKeyName ());
80118 $ index ->delete ($ model ->getKey ());
119+
120+ if ($ this ->geotnt ) {
121+ $ this ->geotnt ->selectIndex ("{$ model ->searchableAs ()}.geoindex " );
122+ $ index = $ this ->geotnt ->getIndex ();
123+ $ index ->loadConfig ($ this ->geotnt ->config );
124+ $ index ->setPrimaryKey ($ model ->getKeyName ());
125+ $ index ->prepareAndExecuteStatement (
126+ 'DELETE FROM locations WHERE doc_id = :documentId; ' ,
127+ [['key ' => ':documentId ' , 'value ' => $ model ->getKey ()]]
128+ );
129+ }
81130 });
82131 }
83132
@@ -145,6 +194,9 @@ protected function performSearch(Builder $builder, array $options = [])
145194 $ index = $ builder ->index ?: $ builder ->model ->searchableAs ();
146195 $ limit = $ builder ->limit ?: 10000 ;
147196 $ this ->tnt ->selectIndex ("{$ index }.index " );
197+ if ($ this ->geotnt ) {
198+ $ this ->geotnt ->selectIndex ("{$ index }.geoindex " );
199+ }
148200
149201 $ this ->builder = $ builder ;
150202
@@ -160,6 +212,14 @@ protected function performSearch(Builder $builder, array $options = [])
160212 $ options
161213 );
162214 }
215+
216+ if (is_array ($ builder ->query )) {
217+ $ location = $ builder ->query ['location ' ];
218+ $ distance = $ builder ->query ['distance ' ];
219+ $ limit = array_key_exists ('limit ' , $ builder ->query ) ? $ builder ->query ['limit ' ] : 10000 ;
220+ return $ this ->geotnt ->findNearest ($ location , $ distance , $ limit );
221+ }
222+
163223 if (isset ($ this ->tnt ->config ['searchBoolean ' ]) ? $ this ->tnt ->config ['searchBoolean ' ] : false ) {
164224 return $ this ->tnt ->searchBoolean ($ builder ->query , $ limit );
165225 } else {
@@ -260,6 +320,13 @@ public function initIndex($model)
260320 $ indexer ->setDatabaseHandle ($ model ->getConnection ()->getPdo ());
261321 $ indexer ->setPrimaryKey ($ model ->getKeyName ());
262322 }
323+ if ($ this ->geotnt && !file_exists ($ this ->tnt ->config ['storage ' ]."/ {$ indexName }.geoindex " )) {
324+ $ indexer = $ this ->geotnt ->getIndex ();
325+ $ indexer ->loadConfig ($ this ->geotnt ->config );
326+ $ indexer ->createIndex ("$ indexName.geoindex " );
327+ $ indexer ->setDatabaseHandle ($ model ->getConnection ()->getPdo ());
328+ $ indexer ->setPrimaryKey ($ model ->getKeyName ());
329+ }
263330 }
264331
265332 /**
@@ -401,5 +468,12 @@ public function flush($model)
401468 if (file_exists ($ pathToIndex )) {
402469 unlink ($ pathToIndex );
403470 }
471+
472+ if ($ this ->geotnt ){
473+ $ pathToGeoIndex = $ this ->geotnt ->config ['storage ' ]."/ {$ indexName }.geoindex " ;
474+ if (file_exists ($ pathToGeoIndex )) {
475+ unlink ($ pathToGeoIndex );
476+ }
477+ }
404478 }
405479}
0 commit comments