简体   繁体   English

查找与Mongo ODM的最佳搭配

[英]Find best match with Mongo ODM

I would like to find the best match with a mongo odm query on Symfony. 我想在Symfony上找到与mongo odm查询最匹配的内容。 I have a function that search for objects with an array of terms. 我有一个功能,可以搜索带有一系列术语的对象。

Here an exemple : 这是一个例子:

I want to search all the users that are nammed 'Paul', 'Peter' and 'Smith'. 我想搜索所有命名为“ Paul”,“ Peter”和“ Smith”的用户。 So my array $search = array('Paul', 'Peter', 'Smith'); 所以我的数组$ search = array('Paul','Peter','Smith');

I have 3 users who match this request : 我有3位使用者符合这个要求:

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

So I would like that this request order the users like this : 所以我希望这个请求可以这样命令用户:

  1. Paul Peter Smith 保罗·彼得·史密斯
  2. Paul Smith 保罗·史密斯
  3. Peter Anderson 彼得·安德森

Here my current method : 这是我目前的方法:

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

    return $users;
}

Do you have any clue on how I can do that ? 您对我该怎么做有任何线索吗?

Thanks 谢谢

Lets forget about php and see how we can achieve that with MongoDB itself (using js) first. 让我们忘了php,看看如何首先使用MongoDB本身(使用js)实现它。

when you want to have "text search" functionality, you have to create a TEXT INDEX on the field you want to search on. 当您要具有“文本搜索”功能时,必须在要搜索的字段上创建一个TEXT INDEX source 资源

that can be achieved by: 可以通过以下方式实现:

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

After this, whenever you do text-searching , you will have some meta data related to your query, which contains some scores that MongoDB generates based on the relevancy of results against keywords. 此后,每当进行文本搜索时 ,您都会有一些与查询相关的元数据 ,其中包含MongoDB根据结果与关键字的相关性生成的一些分数。

So, because you want to have most accurate result first, we should only sort by that scores . 因此,因为您想首先获得最准确的结果,所以我们只应按该分数排序

In your case, it will be: 在您的情况下,它将是:

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

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

Okay. 好的。 This will give you what you want. 这会给你你想要的。 but let convert it to Doctrine query style. 但让我们将其转换为Doctrine查询样式。

For the index: 对于索引:

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

    //...
}

Then run this command to ensure scheme and the index are created: 然后运行以下命令以确保已创建方案和索引:

php app/console doctrine:mongodb:schema:create

and final part: 最后一部分:

$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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM