简体   繁体   English

使用Doctrine的MongoDB ODM - 如何通过嵌入文档的字段查找文档?

[英]Using Doctrine's MongoDB ODM - How do I find documents by embedded documents' fields?

I have the following Documents: 我有以下文件:

  • A User document. User文档。
  • An embedded document, containing a reference to (see next document) 嵌入式文档,包含对(参见下一文档)的引用
  • a Site document Site文档

Each user has an array of embedded documents inside, each representing an item he follows - a site, a twitter account - with the option to mark specific categories he's interested in. Each embedded document has a reference to the third document - the Site document (or Twitter document, etc..). 每个用户都有一系列嵌入式文档,每个用户都代表他所遵循的项目 - 一个站点,一个Twitter帐户 - 可以选择标记他感兴趣的特定类别。每个嵌入式文档都引用第三个文档 - Site文档(或Twitter文件等。)。

The question is - using the MongoDB ODM, how can I get the documents of all the users that chose to follow a given site, using the id of that site ? 问题是 - 使用MongoDB ODM,如何使用该站点的ID获取选择关注给定站点的所有用户的文档?
(see below (after the files) how it is done in the mongodb shell) (见下文(在文件之后)如何在mongodb shell中完成)

User.php user.php的

<?php
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
 * @ODM\Document
 */

class User {
    /**
     * @ODM\Id
     * @var string
     */
    protected $id;

    /**
     * @ODM\EmbedMany(
     *      discriminatorMap={
     *          "site"="SiteFollow",
     *          "twitter"="TwitterFollow",
     *      }
     *  )
     * @var ArrayCollection;
     */
    protected $follows;
}

SiteFollow.php SiteFollow.php

<?php
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
 * @ODM\EmbeddedDocument
 */

class SiteFollow {
    /**
     * @ODM\Collection
     * @var array
     */
    protected $interestingCategories;

    /**
     * @ODM\ReferenceOne(targetDocument="Site", simple=true)
     * @var Site
     */
    protected $siteItem;
}

Site.php Site.php

<?php
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
 * @ODM\Document
 */

class Site {
    /**
     * @ODM\Id
     * @var string
     */
    protected $id;

    /**
     * @ODM\String
     * @var string
     */
    protected $name;

    /**
     * @ODM\String
     * @var string
     */
    protected $url;
}

An example for a user document in the mongo shell: mongo shell中用户文档的示例:

db.User.findOne()
{
    "_id": ObjectId("123"),
    "follows": [
        {
            "interestingCategories": [
                "PHP"
            ]
            "siteItem" : ObjectId("OBJECT_ID_OF_SITE_DOCUMENT"),
            "_doctrine_class_name" : "site"
        }
    ]
}

Mongo shell command for getting all the users that are following a specific site: Mongo shell命令用于获取跟踪特定站点的所有用户:

db.User.find({"follows.siteItem": ObjectId("OBJECT_ID_OF_SITE_DOCUMENT")})

I found that answer provided by Madarco sometimes doesn't work properly. 我发现Madarco提供的答案有时不能正常工作。 If you are querying for the $id field of the reference field in embedded document you may need to pass MongoId object to the equals() method. 如果要查询嵌入文档中引用字段的$id字段,则可能需要将MongoId对象传递给equals()方法。 So in this case it would be: 所以在这种情况下它将是:

$repo = $odm->getRepository('User');
$repo->createQueryBuilder()
    ->field('follows.siteItem.$id')
    ->equals(new \MongoId($siteId))
    ->getQuery()
    ->execute();

Just query for the $id field of the DbRef field siteItem in the SiteFollow document (which is in an embedded collection in the User document): 只需在SiteFollow文档中查询DbRef字段siteItem的$ id字段(该文档位于用户文档中的嵌入式集合中):

$repo = $odm->getRepository("User");
$repo->createQueryBuilder()
         ->field("follows.siteItem.$id")
         ->equals($siteId)
         ->getQuery()
         ->execute();

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

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