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,8 +54,17 @@ 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 )) {
@@ -56,11 +73,25 @@ public function update($models)
5673
5774 if ($ model ->getKey ()) {
5875 $ index ->update ($ model ->getKey (), $ array );
76+ if ($ geoindex ) {
77+ $ geoindex ->prepareAndExecuteStatement (
78+ 'DELETE FROM locations WHERE doc_id = :documentId; ' ,
79+ [['key ' => ':documentId ' , 'value ' => $ model ->getKey ()]]
80+ );
81+ }
5982 } else {
6083 $ index ->insert ($ array );
6184 }
85+ if ($ geoindex && !empty ($ array ['longitude ' ]) && !empty ($ array ['latitude ' ])) {
86+ $ array ['longitude ' ] = (float ) $ array ['longitude ' ];
87+ $ array ['latitude ' ] = (float ) $ array ['latitude ' ];
88+ $ geoindex ->insert ($ array );
89+ }
6290 });
6391 $ index ->indexEndTransaction ();
92+ if ($ this ->geotnt ) {
93+ $ geoindex ->indexEndTransaction ();
94+ }
6495 }
6596
6697 /**
@@ -78,6 +109,17 @@ public function delete($models)
78109 $ index = $ this ->tnt ->getIndex ();
79110 $ index ->setPrimaryKey ($ model ->getKeyName ());
80111 $ index ->delete ($ model ->getKey ());
112+
113+ if ($ this ->geotnt ) {
114+ $ this ->geotnt ->selectIndex ("{$ model ->searchableAs ()}.geoindex " );
115+ $ index = $ this ->geotnt ->getIndex ();
116+ $ index ->loadConfig ($ this ->geotnt ->config );
117+ $ index ->setPrimaryKey ($ model ->getKeyName ());
118+ $ index ->prepareAndExecuteStatement (
119+ 'DELETE FROM locations WHERE doc_id = :documentId; ' ,
120+ [['key ' => ':documentId ' , 'value ' => $ model ->getKey ()]]
121+ );
122+ }
81123 });
82124 }
83125
@@ -145,6 +187,9 @@ protected function performSearch(Builder $builder, array $options = [])
145187 $ index = $ builder ->index ?: $ builder ->model ->searchableAs ();
146188 $ limit = $ builder ->limit ?: 10000 ;
147189 $ this ->tnt ->selectIndex ("{$ index }.index " );
190+ if ($ this ->geotnt ) {
191+ $ this ->geotnt ->selectIndex ("{$ index }.geoindex " );
192+ }
148193
149194 $ this ->builder = $ builder ;
150195
@@ -160,6 +205,14 @@ protected function performSearch(Builder $builder, array $options = [])
160205 $ options
161206 );
162207 }
208+
209+ if (is_array ($ builder ->query )) {
210+ $ location = $ builder ->query ['location ' ];
211+ $ distance = $ builder ->query ['distance ' ];
212+ $ limit = array_key_exists ('limit ' , $ builder ->query ) ? $ builder ->query ['limit ' ] : 10 ;
213+ return $ this ->geotnt ->findNearest ($ location , $ distance , $ limit );
214+ }
215+
163216 if (isset ($ this ->tnt ->config ['searchBoolean ' ]) ? $ this ->tnt ->config ['searchBoolean ' ] : false ) {
164217 return $ this ->tnt ->searchBoolean ($ builder ->query , $ limit );
165218 } else {
@@ -260,6 +313,13 @@ public function initIndex($model)
260313 $ indexer ->setDatabaseHandle ($ model ->getConnection ()->getPdo ());
261314 $ indexer ->setPrimaryKey ($ model ->getKeyName ());
262315 }
316+ if ($ this ->geotnt && !file_exists ($ this ->tnt ->config ['storage ' ]."/ {$ indexName }.geoindex " )) {
317+ $ indexer = $ this ->geotnt ->getIndex ();
318+ $ indexer ->loadConfig ($ this ->geotnt ->config );
319+ $ indexer ->createIndex ("$ indexName.geoindex " );
320+ $ indexer ->setDatabaseHandle ($ model ->getConnection ()->getPdo ());
321+ $ indexer ->setPrimaryKey ($ model ->getKeyName ());
322+ }
263323 }
264324
265325 /**
@@ -401,5 +461,12 @@ public function flush($model)
401461 if (file_exists ($ pathToIndex )) {
402462 unlink ($ pathToIndex );
403463 }
464+
465+ if ($ this ->geotnt ){
466+ $ pathToGeoIndex = $ this ->geotnt ->config ['storage ' ]."/ {$ indexName }.geoindex " ;
467+ if (file_exists ($ pathToGeoIndex )) {
468+ unlink ($ pathToGeoIndex );
469+ }
470+ }
404471 }
405472}
0 commit comments