【问题标题】:how to use ObjectId inside $in query in MongoDB?如何在 MongoDB 的 $in 查询中使用 ObjectId?
【发布时间】:2016-08-02 11:30:17
【问题描述】:

我在 MongoDB 中有以下查询

$this->createQueryBuilder()
            ->field('actor')->in($actorIdArray)
            ->getQuery()
            ->execute();

字段actor是带有注释的对象引用

@MongoDB\ReferenceOne(targetDocument="User", simple=true)

这意味着它将存储对象 ID 而不是完整引用。

当$actorIdArray是一个id数组时

["5706cb39821b166d3931f34f", "56015f7d4f8bd90b769e6e75"]

查询没有返回任何内容,这是预期的,因为归档的 actor 包含对象 id。

但是,如果我以这种方式构建数组

[new MongoId("5706cb39821b166d3931f34f"), new MongoId("56015f7d4f8bd90b769e6e75")]

它也不起作用,这让我很惊讶。

日志显示查询已完成

{ "actor": {"$in":[{"$id":"5706cb39821b166d3931f34f"},{"$id":"56015f7d4f8bd90b769e6e75"}]}}

我认为应该是这样的

{ "actor": {"$in":[ObjectId("5706cb39821b166d3931f34f"),ObjectId("56015f7d4f8bd90b769e6e75"]}}

不确定我是否做错了什么, 有什么想法吗?

【问题讨论】:

  • 它必须是来自 ODM 的文档数组。
  • 如果要避免对象加载,请使用参考doctrine-project.org/api/mongodb_odm/1.0/…
  • @Alsatian 如果我从控制台执行此查询 {"actor": {"$in":[ObjectId("5706cb39821b166d3931f34f"),ObjectId("56015f7d4f8bd90b769e6e75"]}} 则有效无需使用文档数组。
  • Doctrine 序列化你的数组。当您的数组包含文档时,它会将它们转换为 ObjectId(...)。请尝试一下。
  • 无论如何我真的没有文档,所以如果我按照您的建议进行操作,我将需要对 $in 中的每个 id 进行一次查询(可能是数百个项目)。我只需要像在控制台中那样使用学说进行查询(仅使用 id)。希望你 @Alsatian 能帮我解决这个问题

标签: php mongodb symfony doctrine-orm doctrine


【解决方案1】:

正如您在Doctrine\ODM\MongoDB\Query\Builder 的代码源中看到的 -> references 方法:

public function references(object $document) : self
    {
        $this->requiresCurrentField();
        $mapping   = $this->getReferenceMapping();
        $reference = $this->dm->createReference($document, $mapping);
        $storeAs   = $mapping['storeAs'] ?? null;
        $keys      = [];

        switch ($storeAs) {
            case ClassMetadata::REFERENCE_STORE_AS_ID:
                $this->query[$mapping['name']] = $reference;

                return $this;
            .....

        return $this;
    }

您必须知道参考是如何构建的。通常是$id

使用actor.$id作为字段名:

$dm = $this->get('doctrine.odm.mongodb.document_manager'):

$documents = array();
foreach($actorIdArray as $id){
    $documents[] = new MongoDB\BSON\ObjectId($id);
}

$this->createQueryBuilder()
            ->field('actor.$id')->in($documents)
            ->getQuery()
            ->execute();

【讨论】:

    【解决方案2】:

    Doctrine 希望你的数组是一个文档数组。

    您无需查询即可加载document references

    $dm = $this->get('doctrine.odm.mongodb.document_manager'):
    
    $documents = array();
    foreach($actorIdArray as $id){
        $documents[] = $dm->getReference('AppBundle:Actor',$id); // <- this is the key
    }
    
    $this->createQueryBuilder()
                ->field('actor')->in($documents)
                ->getQuery()
                ->execute();
    

    【讨论】:

    • 它不起作用 :( 这是 $dm->getReference 返回的内容 { "initializer": {}, "cloner": { }, "isInitialized": false }
    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 2019-02-21
    • 2015-03-13
    • 1970-01-01
    • 2017-07-22
    • 2017-04-29
    • 2018-08-18
    • 2022-01-14
    相关资源
    最近更新 更多