mongodb查询在命令行返回结果,而在C ++中则没有结果

时间:2019-03-25 08:42:51

标签: c++ mongodb mongodb-query

我通过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)

如果我只是简单地将查询复制/粘贴到db.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。查询时间的差异似乎是缓存预热。我怀疑未经授权的管理员执行警告是外壳在启动时所做的事情,我正在对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 { ... }

0 个答案:

没有答案