执行子查询
perform subquery
文档:
{ "_id":1, "id":1, "list" : [ { "lv" : 1 , "id":1}, {"lv" : 2 , "id":2} ] }
我想查找({"_id":1},{"id":1,"list.lv":1}),但用附加条件限制{"list.lve":1{:"list.id=id"。这意味着我只想检索列表中第一个元素的"id"answers"list.lv"部分,因为它的"list.id"=="id"==1
通常情况下,条件值在代码中提供,但在本例中,该值在文档中。SQL通过子查询或联接表来完成此操作。mongodb在单个查询中支持这一点吗?以及如何在c++驱动程序中编写它?
根据答案,添加c++代码:
mongo::BSONObj res;
std::vector<mongo::BSONObj> pipeline;
pipeline.push_back(BSON("$match"<<BSON("_id"<<1)));
pipeline.push_back(BSON("$unwind"<<"$list"));
mongo::BSONArrayBuilder ab;
ab<<"$id"<<"$list.id";
pipeline.push_back(BSON("$project"<<BSON("id"<<1<<"list.lv"<<1<<"equalsFlag"<<BSON("$subtract"<<ab.arr()))));
pipeline.push_back(BSON("$match"<<BSON("equalsFlag"<<0)));
pipeline.push_back(BSON("$project"<<BSON("id"<<1<<"list.lv"<<1)));
conn->runCommand("db_name", BSON( "aggregate" << "collection_name" << "pipeline" << pipeline ), res);
std::cout<<res["result"].Array()[0].Obj().getObjectField("list").getIntField("lv");
如果我有问题,请尝试这个本地聚合框架查询来完成您需要的内容:
db.collectionName.aggregate(
{"$match" : {"_id" : 1 }},
{"$unwind" : "$list"},
{"$project" : {"id":1, "list.lv" : 1, "equalsFlag" : {"$subtract" : ["$id", "$list.id"]}}},
{"$match" : {"equalsFlag" : 0}},
{"$project" : {"id": 1, "list.lv" : 1}})
让我更详细地解释一下。一开始过滤掉尽可能多的文档是很重要的。我们可以用第一个$匹配。请注意,如果我们在管道的末尾进行{"_id":1}筛选,mongo将无法为其使用索引。$unvent将把每个列表数组元素变成一个单独的文档。然后我们需要比较两个字段。除了$where之外,我不知道有什么简单的方法可以做到这一点,但我们不能将其与聚合框架一起使用。幸运的是,id和list.id都是数字,所以我们可以$从另一个中减去,看看它们是否相等,"equalsFlag":{"$减法":["$id","$list.id"]}。如果它们相等,equalsFlag将为0。因此,我们只添加一个新的$match来获取id=list.id的文档,最后从结果中省略equalsFlag字段,我们还有一个$project。
我不是一个C++爱好者,但我相信C++驱动程序和大多数其他驱动程序一样支持聚合框架。因此,只需在谷歌上搜索一些示例,即可将此原生查询转换为C++查询。这应该相当容易,至少对C#来说是这样。
编辑:来自jean的C++代码以完成答案
mongo::BSONObj res;
std::vector<mongo::BSONObj> pipeline;
pipeline.push_back(BSON("$match"<<BSON("_id"<<1)));
pipeline.push_back(BSON("$unwind"<<"$list"));
mongo::BSONArrayBuilder ab;
ab<<"$id"<<"$list.id";
pipeline.push_back(BSON("$project"<<BSON("id"<<1<<"list.lv"<<1<<"equalsFlag"<<BSON("$subtract"<<ab.arr()))));
pipeline.push_back(BSON("$match"<<BSON("equalsFlag"<<0)));
pipeline.push_back(BSON("$project"<<BSON("id"<<1<<"list.lv"<<1)));
conn->runCommand("db_name", BSON( "aggregate" << "collection_name" << "pipeline" << pipeline ), res);
std::cout<<res["result"].Array()[0].Obj().getObjectField("list").getIntField("lv");
希望它能有所帮助!
- 在C++中异步执行 sql 查询
- 在 MySQL 连接器C++ API 中使用一个函数调用执行多个查询的正确方法是什么?
- 使用C 打开PHP页面(执行查询)
- 如何在 c++ 中设置 ODBC 连接以执行多个查询 (SQLExecDirect)
- 执行“提升几何图形”最近的查询始终首先按最小距离排序结果
- 在什么条件下,数据库在从 cpp 执行选择查询时不会关闭游标
- QODBC连接到SQL Server,但无法执行查询
- 执行子查询
- 正确重复使用ADODB命令对象执行多个查询
- 如何执行异步屏幕外查询
- 使用用户定义的函数对循环/对称值执行Sqlite(C API)和查询(选择)
- C++ 和SQLite - 如何执行由用户输入形成的查询
- 如何使用oracle在sqlapi++中执行多个查询
- 无法使用 Oracle ODBC 执行查询
- 关于条件C++如何执行的简单查询
- 在终止/非活动会话上执行简单查询需要几分钟时间
- 程序在每次执行查询时挂起
- 非常长的查询执行使用c++, Sql Server和ODBC连接
- 插入两个相互引用的SQL表,而无需执行单独的查询
- 每次执行查询时都有新的连接