php mongodb全文搜索和排序

use*_*936 4 php sorting full-text-search mongodb

我需要使用全文索引进行搜索,此代码可以正常工作:

$cursor=$collection->find(array('$text'=>(array('$search'=>$s))),
                    array("score"=> array('$meta'=>"textScore"))
        );
Run Code Online (Sandbox Code Playgroud)

我尝试用以下方法对游标进行排序:

$cursor =$cursor->sort(array("score"=>1));
Run Code Online (Sandbox Code Playgroud)

当我试着读

var_dump($cursor->getNext());
Run Code Online (Sandbox Code Playgroud)

我给了我这个错误未捕获的异常'MongoCursorException'消息'localhost:27017:无法规范化查询:BadValue不能对$ meta投影进行非$ meta排序'

任何的想法?

bjo*_*ori 5

您正在尝试对元字段进行排序,而不是正常的字段名称.

第二个参数用于$collection->find()确定查询返回的文档的哪些字段(是/否).

SELECT *...SELECT field1, field2 ...SQL数据库中的vs 类似.

现在,在MongoDB 2.6中,您可以使用另一个关键字$ meta.此关键字允许您将字段名"注入"到返回文档中(否则实际上不存在).此注入的fieldname的值将来自您正在执行的文档或查询的某种"元数据".

$文本查询运算符是具有可对匹配的文档的详细信息运营商的例子..不幸的是,它没有告诉你有关,因为这样做会操纵意想不到的方式文档这些额外的信息的方式.但它会将元数据附加到文档中 - 由您来决定是否需要它.

$ text运算符创建的元数据使用关键字"textScore".如果要包含该数据,可以通过将其分配给您选择的字段名称来实现:

array("myFieldname" => array('$meta' => 'keyword'))
Run Code Online (Sandbox Code Playgroud)

例如,在$ text search(textScore)的情况下,我们可以通过将此数组作为第二个参数传递给我们的文档中注入fieldname"score" $collection->find():

array("score" => array('$meta' => 'textScore'))
Run Code Online (Sandbox Code Playgroud)

现在我们在返回文档中注入一个名为"score"的字段,该文档具有来自$ text搜索的"textScore"值.

但由于这仍然只是文档的元数据,如果您想在执行查询之前继续在任何后续操作中使用此值,您仍然必须将其称为$ meta数据.

这意味着,要对字段进行排序,您必须对$ meta投影进行排序

array('score' => array('$meta' => 'textScore'))
Run Code Online (Sandbox Code Playgroud)

您的完整示例将变为:

<?php
$mc = new MongoClient();


$collection = $mc->selectCollection("myDatabase", "myCollection");

$string = "search string";
$cursor = $collection->find(
    array('$text' => array('$search' => $string)),
    array('score' => array('$meta' => 'textScore'))
);

$cursor = $cursor->sort(
    array('score' => array('$meta' => 'textScore'))
);

foreach($cursor as $document) {
    var_dump($document);
}
Run Code Online (Sandbox Code Playgroud)