使用聚合管道进行文本搜索 - MongoDB / PHP

Posted

技术标签:

【中文标题】使用聚合管道进行文本搜索 - MongoDB / PHP【英文标题】:Text search with aggregation pipeline - MongoDB / PHP 【发布时间】:2016-08-23 18:54:41 【问题描述】:

我正在尝试在 MongoDB 3.2 中使用聚合管道实现文本搜索 这就是我的 mongo 查询的样子:

    db.revws.aggregate(
   [
      $match:  $text:  $search: "terrible"   ,
      $sort:  score:  $meta: "textScore"   ,
      $project: score:  $meta: "textScore" ,'ProductInfo.ProductID' :1 ,  'Reviews.Title': 1, 'Reviews.Content': 1, 'Reviews.Overall': 1,'Reviews.Author': 1, _id: 0   
   ]
)

这在我的收藏中运行良好。生成的文档结构如下所示:


    "Reviews" : 
        "Title" : "Terrible terrible terrible",
        "Author" : "C. Leinart",
        "Overall" : "1.0",
        "Content" : "I love cameras - i have multiple cameras for multiple uses and this is the absolute worst ever.  The quality of the prints are terrible.  The paper turns sort of a bluish color.  The battery life is terrible and to top it all off, i lost my charger and there is no such thing as a replacement charger in Polaroid-land.  Really...you CANNOT buy a replacement charger.  So if you have one of these, hang on to the charger and be prepared to only use for fun party pics - it's novel but not worth the $$."
    ,
    "ProductInfo" : 
        "ProductID" : "B005O08KH6"
    ,
    "score" : 2.53571428571429

当我尝试根据用户在 php 中的输入执行类似的文本搜索查询时。我收到一个错误“$project 规范必须是一个对象”。

这是我的 PHP 代码:

<html>
<body>
<h3>MongoDB Test - Aggregation pipeline</h3>
<h2>Text search - Amazon reviews</h2>
<br>
<form method="post">
search: <input type="text" name="term"><br><br>
<input type="submit" value="Display results">
</form>
</body>
</html>

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") 
   $term = $_REQUEST['term'];
   // connect to mongodb : default is localhost:27017
   $m = new MongoClient();
   echo "Connection to database successfully"."</br>";
   $db = $m->selectDB('test');
   $collection = new MongoCollection($db, 'revws');
/*
db.revws.aggregate(
   [
      $match:  $text:  $search: "terrible"   ,
      $sort:  score:  $meta: "textScore"   ,
      $project: score:  $meta: "textScore" ,'ProductInfo.ProductID' :1 ,  'Reviews.Title': 1, 'Reviews.Content': 1, 'Reviews.Overall': 1,'Reviews.Author': 1, _id: 0   
   ]
)
 * 
 */
$pipeline = array (
    array(
      '$match' => array('$text' => array('$search'=> $term))
    ),
    array('$sort' => array("score" => array('$meta' => "textScore"))
    ),
    array('$project' => array( array("score" => array('$meta' => "textScore"), 'ProductInfo.ProductID' => 1, 
        'Reviews.Title' => 1, 'Reviews.Content' => 1 , 'Reviews.Overall' => 1, 'Reviews.Author' => 1, '_id' => 0
                 )
    )
    ) 
);
var_dump($pipeline);
$cursor = $collection->aggregate($pipeline);
echo "<br><br>";
echo '<table border="1"><tr><td>text score</td><td>ProductID</td><td>Review Title</td><td>Content</td><td>Author</td><td>Rating</td></tr>';

foreach ($cursor as $doc) 

  echo '<tr>';
      echo
           '<td>'.$doc['score'].'</td>'.
           '<td>'.$doc['ProductInfo']['ProductID'].'</td>'.
           '<td>'.$doc['Reviews']['Title'].'</td>'.
           '<td>'.$doc['Reviews']['Content'].'</td>'.
           '<td>'.$doc['Reviews']['Author'].'</td>'.
           '<td>'.$doc['Reviews']['Overall'].'</td>';
  echo '</tr>';

echo '</table>';

?> 

这个php的输出是:

连接数据库成功 array(3) [0]=> array(1) ["$match"]=> 数组(1) ["$text"]=> 数组(1) ["$search"]=> 字符串(8) “可怕” [1]=> 数组(1) [“$sort”]=> 数组(1) [“分数”]=> 数组(1)[“$meta”]=>字符串(9)“textScore”[2]=>数组(1) ["$project"]=> array(1) [0]=> array(7) ["score"]=> array(1) ["$meta"]=> string(9) "textScore" ["ProductInfo.ProductID"]=> int(1) ["Reviews.Title"]=> int(1) ["Reviews.Content"]=> int(1) ["Reviews.Overall"]=> int(1) ["Reviews.Author"]=> int(1) ["_id"]=> int(0) 致命错误:未捕获的异常“MongoResultException” 带有消息 'localhost:27017: $project 规范必须是 C:\xampp\htdocs\MongoSearch\MongoSearchAggr.php:49 堆栈中的对象' 跟踪:#0 C:\xampp\htdocs\MongoSearch\MongoSearchAggr.php(49): MongoCollection->aggregate(Array) #1 main 抛出 C:\xampp\htdocs\MongoSearch\MongoSearchAggr.php 第 49 行

我有意将 var_dump 用于显示基于 php 的 mongo 查询。 谁能指出这里的错误? 谢谢

【问题讨论】:

【参考方案1】:

你试过了吗

$pipeline = array (
    array(
      '$match' => array('$text' => array('$search'=> $term))
    ),
    array('$sort' => array("score" => array('$meta' => "textScore"))
    ),
    array('$project' => array("score" => array('$meta' => "textScore"), 'ProductInfo.ProductID' => 1, 
        'Reviews.Title' => 1, 'Reviews.Content' => 1 , 'Reviews.Overall' => 1, 'Reviews.Author' => 1, '_id' => 0

    )
    ) 
);

我刚刚从 $project 中删除了一个额外的数组

【讨论】:

以上是关于使用聚合管道进行文本搜索 - MongoDB / PHP的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB:在聚合管道中使用字符串操作

mongoDB表与表的关系及聚合管道查询

MongoDB 聚合管道(Aggregation Pipeline)

MongoDB聚合管道组

mongodb聚合命令

在mongodb聚合管道中将毫秒转换为日期以进行分组?