寻找与Mongo ODM的最佳匹配

时间:2015-12-07 10:46:05

标签: php mongodb symfony mongodb-query

我想在Symfony上找到与mongo odm查询的最佳匹配。我有一个函数,用一组术语搜索对象。

这是一个例子:

我想搜索所有被称为“保罗”,“彼得”和“史密斯”的用户。 所以我的数组$ search = array('Paul','Peter','Smith');

我有3位符合此要求的用户:

  • 彼得安德森
  • Paul Smith
  • 保罗彼得史密斯

所以我希望这个请求命令用户这样:

  1. 保罗彼得史密斯
  2. Paul Smith
  3. 彼得安德森
  4. 这是我目前的方法:

        public function search($search) {
        $query = $this->createQueryBuilder('AcmeDataBundle:users');
        $users = $query
            ->field('name')->in($search)
            ->getQuery()->execute();
    
        return $users;
    }
    

    你对我如何做到这一点有什么线索吗?

    由于

1 个答案:

答案 0 :(得分:1)

让我们忘记php,看看我们如何通过MongoDB本身(使用js)来实现它。

当你想要"文本搜索"功能,您必须在要搜索的字段上创建TEXT INDEX source

可以通过以下方式实现:

db.yourCollectionName.createIndex({ fieldName: "text" })

在此之后,每当您进行文本搜索时,您的查询都会有一些meta data,其中包含MongoDB根据结果与关键字的相关性生成的一些分数。

因此,因为您希望首先获得最准确的结果,所以我们只应按该分数排序

在您的情况下,它将是:

db.User.createIndex( { name: "text" } )

db.User.find( 
    {$text:{$search:"Paul Smith Peter"}},
    { score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" } } );

好。这会给你你想要的。但是让它转换为Doctrine查询样式。

索引:

/**
 * @ODM\Document
 * @ODM\Indexes({
 *   @ODM\Index(keys={"name"="text"})
 * })
 */
class User{    
    /** @ODM\String */
    private $name;

    //...
}

然后运行此命令以确保方案和索引已创建:

php app/console doctrine:mongodb:schema:create

和最后一部分:

$search = ['Paul', 'Peter', 'Smith'];

$names = implode(' ', $search);

$queryBuilder = $documentManager->createQueryBuilder('User');

$expr = $queryBuilder->expr()->operator('$text', array('$search' => $names));

$result = $queryBuilder
            ->equals($expr->getQuery())
            ->sortMeta('score', 'textScore')
            ->getQuery();

foreach ($result as $user) {
    var_dump($user);
}