我在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();
我正在尝试从该集合中选择其中remaining_attempts大于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
}
]
但是,原始问题仍然适用。
答案 0 :(得分:2)
您可以使用点表示法来引用集合中的元素。
$qb->field('delivery_attempts.remaining_attempts')->gt(0)
->field('delivery_attempts.live_feed_id')->equals(107);
答案 1 :(得分:0)
如果我在mongo上运行查询,它对我来说很好。
db.testQ.find({"delivery_attempts.remaining_attempts" : {"$gt" : 0}, "delivery_attempts.live_feed_id" : 107}).pretty()
所以你的PHP查询似乎有问题,我建议运行profiler来查看哪个查询实际上是针对mongo运行的
db.setProfilingLevel(2)
这将记录您启用分析后的所有操作。然后,您可以查询日志以查看实际查询
db.system.profile.find().pretty()
这可能会帮助您找到罪魁祸首。
答案 2 :(得分:0)
听起来你解决了第一个问题,即使用Hash
类型映射(而不是存储BSON对象或PHP中的关联数组)而不是Collection
映射(用于实际数组) );但是,您提交的answer中的查询条件似乎仍然不正确。
$qb->field('delivery_attempts.remaining_attempts')->gt(0)
->field('delivery_attempts.live_feed_id')->equals(107);
你在原来的问题中说过:
我正在尝试从该集合中选择其中remaining_attempts大于0且live_feed_id等于107的任何数据。
我假设您希望delivery_attempts
数组中的单个元素满足该条件。如果这是正确的,那么您在上面指定的条件可能会超出预期,因为delivery_attempts.remaining_attempts
可以引用数组中的任何元素,live_feed_id
条件也是如此。您需要使用$elemMatch
将字段条件限制为单个数组元素。
我发现您在原始问题中使用elemMatch()
,但语法看起来有点奇怪。除非您尝试将两个查询运算符应用于同一字段名称,否则不应使用addAnd()
(即$and
运算符)。只需将额外的field()
次调用添加到您用于elemMatch()
方法的同一查询表达式中。 ODM测试套件的一个例子是QueryTest::testElemMatch()
。您还可以在查询上使用debug()
方法查看由ODM查询构建器创建的原始MongoDB查询对象。