为什么这两个MongoDB查询不同?

时间:2015-02-28 18:19:21

标签: mongodb mongodb-query

我是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)的混合,则它“失败”。

但显式$中的同一组谓词将会“成功”。

我只是想知道这种行为是否是预期的,如果是,为什么。

2 个答案:

答案 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