From 062e138c836c2a80e61d1261f4af8fd72a6e6692 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Thu, 5 Dec 2013 21:09:33 +0200 Subject: [PATCH] Method "\yii\mongo\Collection::fullTextSearch()" added. --- extensions/mongo/Collection.php | 46 +++++++++++++++++++++++++- tests/unit/extensions/mongo/CollectionTest.php | 31 +++++++++++++++++ tests/unit/extensions/mongo/MongoTestCase.php | 11 ++++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/extensions/mongo/Collection.php b/extensions/mongo/Collection.php index 5b6c829..e9c37b8 100644 --- a/extensions/mongo/Collection.php +++ b/extensions/mongo/Collection.php @@ -176,6 +176,7 @@ class Collection extends Object * @param string|array $columns column name or list of column names. * If array is given, each element in the array has as key the field name, and as * value either 1 for ascending sort, or -1 for descending sort. + * Use value 'text' to specify text index. * You can specify field using native numeric key with the field name as a value, * in this case ascending sort will be used. * For example: @@ -183,6 +184,7 @@ class Collection extends Object * [ * 'name', * 'status' => -1, + * 'description' => 'text', * ] * ~~~ * @throws Exception on failure. @@ -540,7 +542,6 @@ class Collection extends Object if (!empty($condition)) { $command['query'] = $this->buildCondition($condition); } - $token = $this->composeLogToken('mapReduce', [$map, $reduce, $out]); Yii::info($token, __METHOD__); try { @@ -557,6 +558,49 @@ class Collection extends Object } /** + * Performs full text search. + * @param string $search string of terms that MongoDB parses and uses to query the text index. + * @param array $condition criteria for filtering a results list. + * @param array $fields list of fields to be returned in result. + * @param integer $limit the maximum number of documents to include in the response (by default 100). + * @param string $language he language that determines the list of stop words for the search + * and the rules for the stemmer and tokenizer. If not specified, the search uses the default + * language of the index. + * @return array the highest scoring documents, in descending order by score. + * @throws Exception on failure. + */ + public function fullTextSearch($search, $condition = [], $fields = [], $limit = null, $language = null) { + $command = [ + 'search' => $search + ]; + if (!empty($condition)) { + $command['filter'] = $this->buildCondition($condition); + } + if (!empty($fields)) { + $command['project'] = $fields; + } + if ($limit !== null) { + $command['limit'] = $limit; + } + if ($language !== null) { + $command['language'] = $language; + } + $token = $this->composeLogToken('text', $command); + Yii::info($token, __METHOD__); + try { + Yii::beginProfile($token, __METHOD__); + $command = array_merge(['text' => $this->getName()], $command); + $result = $this->mongoCollection->db->command($command); + $this->tryResultError($result); + Yii::endProfile($token, __METHOD__); + return $result['results']; + } catch (\Exception $e) { + Yii::endProfile($token, __METHOD__); + throw new Exception($e->getMessage(), (int)$e->getCode(), $e); + } + } + + /** * Checks if command execution result ended with an error. * @param mixed $result raw command execution result. * @throws Exception if an error occurred. diff --git a/tests/unit/extensions/mongo/CollectionTest.php b/tests/unit/extensions/mongo/CollectionTest.php index a50177d..153ffa9 100644 --- a/tests/unit/extensions/mongo/CollectionTest.php +++ b/tests/unit/extensions/mongo/CollectionTest.php @@ -279,4 +279,35 @@ class CollectionTest extends MongoTestCase $indexInfo = $collection->mongoCollection->getIndexInfo(); $this->assertEquals(1, count($indexInfo)); } + + /** + * @depends testBatchInsert + * @depends testCreateIndex + */ + public function testFullTextSearch() + { + if (version_compare('2.4', $this->getServerVersion(), '>')) { + $this->markTestSkipped("Mongo Server 2.4 required."); + } + + $collection = $this->getConnection()->getCollection('customer'); + + $rows = [ + [ + 'name' => 'customer 1', + 'status' => 1, + 'amount' => 100, + ], + [ + 'name' => 'some customer', + 'status' => 1, + 'amount' => 200, + ], + ]; + $collection->batchInsert($rows); + $collection->createIndex(['name' => 'text']); + + $result = $collection->fullTextSearch('some'); + $this->assertNotEmpty($result); + } } \ No newline at end of file diff --git a/tests/unit/extensions/mongo/MongoTestCase.php b/tests/unit/extensions/mongo/MongoTestCase.php index eefb972..291debd 100644 --- a/tests/unit/extensions/mongo/MongoTestCase.php +++ b/tests/unit/extensions/mongo/MongoTestCase.php @@ -135,4 +135,15 @@ class MongoTestCase extends TestCase } return $result; } + + /** + * Returns the Mongo server version. + * @return string Mongo server version. + */ + protected function getServerVersion() + { + $connection = $this->getConnection(); + $buildInfo = $connection->getDatabase()->executeCommand(['buildinfo' => true]); + return $buildInfo['version']; + } } \ No newline at end of file