我是MongoDB的新手。
鉴于此文件:
{ "x" : 5, "y" : 1 }
此查询与之匹配:
{ "$and" : [ {"y" : 1}, {"$or" : [ {"x" : 1}, {"x" : 5} ] } ] }
但这个没有:
{ "y" : 1, "$or" : [ {"x" : 1}, {"x" : 5} ] }
有原因吗?
更进一步:
我可以将查询简化为“退化”$或大小写:
{ "y" : 1, "$or" : [ {"x" : 5} ] }
它仍然不匹配。但是这个确实:
{ "y" : 1, "x" : 5 }
这个也是如此:
{ "$or" : [ { "y" : 1 } ], "$or" : [ { "x" : 5 } ] }
通常,当顶级查询文档中包含多个谓词时,它们似乎被视为隐式AND。这似乎与文档一致。
但是如果“顶级隐式AND”中的谓词是逻辑($和/ $或)与文字比较(y:1)的混合,则它“失败”。
但显式$中的同一组谓词将会“成功”。
我只是想知道这种行为是否是预期的,如果是,为什么。
答案 0 :(得分:1)
所有这些查询都有效。
> db.test.drop()
true
> db.test.insert({ "x" : 5, "y" : 1 })
WriteResult({ "nInserted" : 1 })
> db.test.find({ "$and" : [ {"y" : 1}, {"$or" : [ {"x" : 1}, {"x" : 5} ] } ] })
{ "_id" : ObjectId("54f20e0a0d484029bca053c4"), "x" : 5, "y" : 1 }
> db.test.find({ "y" : 1, "$or" : [ {"x" : 1}, {"x" : 5} ] })
{ "_id" : ObjectId("54f20e0a0d484029bca053c4"), "x" : 5, "y" : 1 }
> db.test.find({ "y" : 1, "$or" : [ {"x" : 5} ] })
{ "_id" : ObjectId("54f20e0a0d484029bca053c4"), "x" : 5, "y" : 1 }
答案 1 :(得分:1)
如果有人后来看到这个,那么接下来就是这样:
简而言之,当使用mongo C驱动程序时,查询失败"从来没有真正被发送到Mongo服务器。我从来没有注意到这一点,因为我没有检查错误。
我的代码看起来像这样:
mongoc_cursor_t *cursor = mongoc_collection_find(whatever);
const bson_t *doc_mongo = NULL;
while (mongoc_cursor_next(cursor, &doc_mongo))
{
whatever
}
但在那之后,我需要有类似以下代码段的内容来查看错误消息:
if (mongoc_cursor_error (cursor, &error))
{
fprintf (stderr, "Failed to iterate all documents: %s\n", error.message);
}
我看到的错误信息看起来像这样:
"Cannot mix top-level query with dollar keys such as..."
修复方法是始终将查询文档包装在密钥" $ query"下的另一个文档中。
bson_t* wrap(bson_t* q)
{
bson_t *b = bson_new ();
bson_append_document(b, "$query", -1, q);
return b;
}
在此处找到更多信息:
http://qnalist.com/questions/5650929/mongodb-user-cdriver-cannot-use-or-and-in-find-queries