c++ - mongodb 查询在命令行返回结果,在 C++ 中没有结果
问题描述
我通过 C++ 查询 mongodb。一个特定的查询奇怪地没有通过 C++ 返回任何结果,但在 mongo shell 上工作正常(使用相同的凭据)。我试图了解它们为什么不同以及如何使 C++ 查询工作。
这是 C++ 中的代码:
bsoncxx::builder::basic::document match_records;
match_records.append(kvp("$and", [&group_id](sub_array sub_and) {
LOGGABLE;
sub_and.append([&group_id](sub_document and_sub_doc_1) {
and_sub_doc_1.append(kvp("$or", [&group_id](sub_array sub_or) {
sub_or.append([&group_id](sub_document fg_id) {
fg_id.append(kvp("focus_group_id", group_id.GroupId()));
});
sub_or.append([&group_id](sub_document rg_id) {
rg_id.append(kvp("reading_group_id", group_id.GroupId()));
});
}));
});
if (something true) {
sub_and.append([&group_id](sub_document and_sub_doc_2) {
and_sub_doc_2.append(kvp("$or", [&group_id](sub_array sub_or) {
sub_or.append([&group_id](sub_document or_sub_stream) {
or_sub_stream.append(
kvp("event_category", "focus_group"));
or_sub_stream.append(
kvp("event_category", [](sub_document subdoc) {
subdoc.append(kvp("$exists", 0));
}));
});
}));
});
} else { ... }
sub_and.append([&group_id](sub_document and_sub_doc_4) {
and_sub_doc_4.append(kvp("utm", [](sub_document subdoc) {
subdoc.append(kvp("$exists", 1));
}));
});
}));
LOG_INFO << bsoncxx::to_json(match_records);
最后的日志行发出这个(为了便于阅读,我已经重新格式化):
{
"$and": [
{
"$or": [
{
"focus_group_id": 465
},
{
"reading_group_id": 465
}
]
},
{
"$or": [
{
"event_category": "focus_group",
"event_category": {
"$exists": 0
}
}
]
},
{
"utm": {
"$exists": 1
}
}
]
}
我因此执行该查询:
bsoncxx::builder::basic::document project_fields;
project_fields.append(kvp("_id", 1), kvp("focus_group_id", 1),
kvp("reading_group_id", 1), kvp("user_id", 1),
kvp("device_id", 1), kvp("event", 1),
kvp("event_category", 1), kvp("server_time", 1),
kvp("details", 1), kvp("utm", 1));
mongocxx::options::find opts{};
opts.projection(project_fields.view());
mongocxx::collection candy_events = mongo_db["candy_events"];
mongocxx::cursor cursor = candy_events.find(match_records.view(), opts);
for (const bsoncxx::document::view& doc : cursor) {
...
并看到 for 循环体从未被执行(查询不返回任何结果)。
观察 mongod 日志,我看到收到的查询没有标记错误:
2019-03-25T08:13:27.864Z I NETWORK [conn6] received client metadata from x,y,z.w:49840 conn6: { driver: { name: "mongoc / mongocxx", version: "1.13.1-dev / 3.4.0" }, os: { type: "Linux", name: "Ubuntu", version: "16.04", architecture: "x86_64" }, platform: "cfg=0x215680e9 posix=200809 stdc=201112 CC=GCC 5.4.0 20160609 CFLAGS="" LDFLAGS=""" }
2019-03-25T08:13:27.888Z I ACCESS [conn6] Successfully authenticated as principal analytics-staging on example_staging
2019-03-25T08:13:32.104Z I COMMAND [conn6] command example_staging.candy_events command: find { find: "candy_events", filter: { $and: [ { $or: [ { focus_group_id: 465 }, { reading_group_id: 465 } ] }, { $or: [ { event_category: "focus_group", event_category: { $exists: 0 } } ] }, { utm: { $exists: 1 } } ] }, projection: { _id: 1, focus_group_id: 1, reading_group_id: 1, user_id: 1, device_id: 1, event: 1, event_category: 1, server_time: 1, details: 1, utm: 1 }, $db: "example_staging", $readPreference: { mode: "primaryPreferred" }, lsid: { id: UUID("ed852824-f336-40a6-a5c4-54b36439e03b") } } planSummary: COLLSCAN keysExamined:0 docsExamined:899850 cursorExhausted:1 numYields:7030 nreturned:0 reslen:104 locks:{ Global: { acquireCount: { r: 14062 } }, Database: { acquireCount: { r: 7031 } }, Collection: { acquireCount: { r: 7031 } } } protocol:op_msg 1043ms
2019-03-25T08:13:32.109Z I NETWORK [conn6] end connection x.y.z.w:49840 (1 connection now open)
如果我只是将查询复制/粘贴到 adb.candy_events.find()
中,我确实会返回结果,并且日志显示如下:
2019-03-25T08:19:50.566Z I NETWORK [listener] connection accepted from x.y.z.w:40570 #11 (2 connections now open)
2019-03-25T08:19:50.569Z I NETWORK [conn11] received client metadata from x.y.z.w:40570 conn11: { application: { name: "MongoDB Shell" }, driver: { name: "MongoDB Internal Client", version: "3.6.5" }, os: { type: "Linux", name: "Ubuntu", architecture: "x86_64", version: "16.04" } }
2019-03-25T08:19:50.585Z I ACCESS [conn11] Successfully authenticated as principal analytics-staging on example_staging
2019-03-25T08:19:50.586Z I ACCESS [conn11] Unauthorized: not authorized on admin to execute command { getLog: "startupWarnings", $db: "admin" }
2019-03-25T08:19:50.588Z I ACCESS [conn11] Unauthorized: not authorized on admin to execute command { replSetGetStatus: 1.0, forShell: 1.0, $db: "admin" }
2019-03-25T08:20:07.031Z I COMMAND [conn11] command example_staging.candy_events appName: "MongoDB Shell" command: find { find: "candy_events", filter: { $and: [ { $or: [ { focus_group_id: 465.0 }, { reading_group_id: 465.0 } ] }, { $or: [ { event_category: { $exists: 0.0 } } ] }, { utm: { $exists: 1.0 } } ] }, $db: "example_staging" } planSummary: COLLSCAN cursorid:116556503976 keysExamined:0 docsExamined:884119 numYields:6907 nreturned:101 reslen:77090 locks:{ Global: { acquireCount: { r: 13816 } }, Database: { acquireCount: { r: 6908 } }, Collection: { acquireCount: { r: 6908 } } } protocol:op_msg 628ms
2019-03-25T08:20:30.732Z I NETWORK [conn11] end connection x.y.z.w:40570 (1 connection now open)
这是 mongod 3.6.5。查询时间的差异似乎是缓存变暖。我怀疑未经授权的管理员执行警告是 shell 在启动时所做的事情,我正在针对 example_staging 进行身份验证。
有什么建议我可能做错了什么或如何进行这项工作?
更新/解决方案
感谢@neil-lunn 建议使用分析器,我发现我的 C++ 调用中有一个小错误。中间从句应该是这样的:
if (something true) {
sub_and.append([&group_id](sub_document and_sub_doc_2) {
and_sub_doc_2.append(kvp("$or", [&group_id](sub_array sub_or) {
sub_or.append([&group_id](sub_document is_fg) {
is_fg.append(kvp("event_category", "focus_group"));
});
sub_or.append([&group_id](sub_document is_absent) {
is_absent.append(
kvp("event_category", [](sub_document subdoc) {
subdoc.append(kvp("$exists", 0));
}));
});
}));
});
} else { ... }
解决方案
推荐阅读
- php - 我遇到了这个问题(htmlspecialchars)
- python - 使用 Python 在 Selenium WebDriver 中按 Escape 不起作用
- python - 融化熊猫中的多索引数据框
- r - 用 gt 中的条件信息为单元格着色
- php - 如何使用 phpunit 对 if 语句执行断言
- node.js - 我需要在Angular的每个pdf页面中添加一些设计的页脚
- python - 用于 pySpark 项目的 Azure DevOps CI 管道
- c++ - 在 C++ 中的 3d 数组堆上分配
- android - 如何在android compose中以黑白显示图像
- ios - Not able to create IOS build from Xcode using Flutter code?