【问题标题】:Select condition within a hash column using Doctrine mongoDB ODM query builder使用 Doctrine mongoDB ODM 查询生成器在哈希列中选择条件
【发布时间】:2014-02-17 13:03:20
【问题描述】:

我在 mongoDB 集合中有以下结构:

{
        "_id" : ObjectId("5301d337fa46346a048b4567"),
        "delivery_attempts" : {
                "0" : {
                        "live_feed_id" : 107,
                        "remaining_attempts" : 2,
                        "delivered" : false,
                        "determined_status" : null,
                        "date" : 1392628536
                }
        }
}

// > db.lead.find({}, {delivery_attempts:1}).pretty();

我正在尝试从该集合中选择所有剩余尝试次数大于 0 且 live_feed_id 等于 107 的数据。请注意,“delivery_attempts”字段属于哈希类型。

我尝试在 elemMatch 中使用 addAnd(不确定这是否是实现此目的的正确方法)。

    $qb = $this->dm->createQueryBuilder($this->getDocumentName());

    $qb->expr()->field('delivery_attempts')
        ->elemMatch(
            $qb->expr()
                ->field('remaining_attempts')->gt(0)
                ->addAnd($qb->expr()->field('live_feed_id')->equals(107))
    );

我似乎确实得到了上面详述的记录。然而,改变大于 测试到 3

->field('remaining_attempts')->gt(3)

仍然返回记录(这是不正确的)。有没有办法做到这一点?


编辑:我已将 delivery_attempts 字段类型从“哈希”更新为“集合”。这表明数据被存储为数组而不是对象:

    "delivery_attempts" : [
            {
                    "live_feed_id" : 107,
                    "remaining_attempts" : 2,
                    "delivered" : false,
                    "determined_status" : null,
                    "date" : 1392648433
            }
    ]

但是,原来的问题仍然适用。

【问题讨论】:

  • 只是出于好奇,您所说的“请注意“delivery_attempts”字段属于哈希类型”是什么意思?我从未听说过哈希类型,只有哈希索引,非常感谢您参考文档,谢谢!编辑评论:哦,没关系,看起来它是学说中的一种类型,而不是 mongodb 本身。

标签: php mongodb doctrine doctrine-odm


【解决方案1】:

您可以使用点表示法来引用集合中的元素。

    $qb->field('delivery_attempts.remaining_attempts')->gt(0)
       ->field('delivery_attempts.live_feed_id')->equals(107);

【讨论】:

  • 哦,对不起,没注意到你的回答,看来你解决了问题
【解决方案2】:

如果我在 mongo 上运行查询,它对我来说很好。

db.testQ.find({"delivery_attempts.remaining_attempts" : {"$gt" : 0}, "delivery_attempts.live_feed_id" : 107}).pretty()

所以您的 PHP 查询似乎有问题,我建议运行分析器以查看实际针对 mongo 运行的查询

db.setProfilingLevel(2)

这将记录您启用分析后的所有操作。然后你可以查询日志,看看实际查询的是哪些

db.system.profile.find().pretty()

这可能会帮助您找到罪魁祸首。

【讨论】:

    【解决方案3】:

    听起来你解决了你的第一个问题,即使用 Hash 类型映射(而不是用于存储 BSON 对象或 PHP 中的关联数组)而不是 Collection 映射(用于真实数组);但是,您提交的answer 中的查询条件似乎仍然不正确。

    $qb->field('delivery_attempts.remaining_attempts')->gt(0)
       ->field('delivery_attempts.live_feed_id')->equals(107);
    

    你在原来的问题中说:

    我正在尝试从该集合中选择剩余尝试次数大于 0 且 live_feed_id 等于 107 的任何数据。

    我假设您希望 delivery_attempts 数组中的单个元素满足该条件。如果这是正确的,那么您在上面指定的条件可能会比您预期的更匹配,因为 delivery_attempts.remaining_attempts 可以引用数组中的 any 元素,live_feed_id 条件也可以。您需要使用 $elemMatch 将字段条件限制为单个数组元素。

    我看到您在原始问题中使用了elemMatch(),但语法看起来有点奇怪。除非您尝试将两个查询运算符应用于相同的字段名称,否则不需要使用 addAnd()(即 $and 运算符)。只需将额外的field() 调用添加到您用于elemMatch() 方法的同一查询表达式。 ODM 的测试套件中的一个示例是QueryTest::testElemMatch()。您还可以在查询上使用debug() 方法来查看由 ODM 的查询构建器创建的原始 MongoDB 查询对象。

    【讨论】:

      猜你喜欢
      • 2014-04-19
      • 1970-01-01
      • 2018-07-29
      • 2014-08-05
      • 2014-05-23
      • 1970-01-01
      • 2018-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多