2

Following is the code trying to use mongo query with project find option.

    using bsoncxx::builder::stream::document;
    mongocxx::options::find opts;
    document condition, options;

    const static int readdomain = 90000;

    condition << "lastRead" << open_document << "$gte" << readdomain << close_document;
    options << "read" << 1;
    opts.projection(options.view());
    mongocxx::cursor cursor = collection.find(condition.view(), opts);

The above query without "opts" can work well while the one with "opts" will raise the following error.

terminate called after throwing an instance of 'bsoncxx::v_noabi::exception'
  what():  unset document::element
[zy1989:20594] *** Process received signal ***
[zy1989:20594] Signal: Aborted (6)
[zy1989:20594] Signal code:  (-6)
[zy1989:20594] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x10d10)[0x7f05d3b65d10]
[zy1989:20594] [ 1] /lib/x86_64-linux-gnu/libc.so.6(gsignal+0x37)[0x7f05d37c0267]
[zy1989:20594] [ 2] /lib/x86_64-linux-gnu/libc.so.6(abort+0x16a)[0x7f05d37c1eca]
[zy1989:20594] [ 3] /usr/lib/x86_64-linux-gnu/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x16d)[0x7f05d471106d]
[zy1989:20594] [ 4] /usr/lib/x86_64-linux-gnu/libstdc++.so.6(+0x5eee6)[0x7f05d470eee6]
[zy1989:20594] [ 5] /usr/lib/x86_64-linux-gnu/libstdc++.so.6(+0x5ef31)[0x7f05d470ef31]
[zy1989:20594] [ 6] /usr/lib/x86_64-linux-gnu/libstdc++.so.6(+0x5f149)[0x7f05d470f149]
[zy1989:20594] [ 7] /usr/local/lib/libbsoncxx.so._noabi(_ZNK7bsoncxx7v_noabi8document7element4typeEv+0xdd)[0x7f05d49cfe0d]
[zy1989:20594] [ 8] /usr/local/lib/libbsoncxx.so._noabi(_ZN7bsoncxx7v_noabi7to_jsonENS0_8document7elementE+0x286)[0x7f05d49d8926]
[zy1989:20594] [ 9] ./ArticleIndexComputation(_Z7groupbyN8mongocxx7v_noabi6cursor8iteratorElRSt6vectorIN7bsoncxx7v_noabi8document4viewESaIS7_EERSt3mapIiS3_IiSaIiEESt4lessIiESaISt4pairIKiSD_EEE+0x186)[0x415826]
[zy1989:20594] [10] ./ArticleIndexComputation(main+0x1181)[0x417161]
[zy1989:20594] [11] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f05d37aba40]
[zy1989:20594] [12] ./ArticleIndexComputation(_start+0x29)[0x415439]
[zy1989:20594] *** End of error message ***
Leo Zhao
  • 77
  • 1
  • 12
  • Can you get a symbolized stack trace, hopefully with line numbers? Try running your program under GDB. Also, please provide some information about what version of the driver you are using, what toolchain, platform, etc. – acm Mar 09 '16 at 18:15
  • I have got what exactly have gone wrong. – Leo Zhao Mar 10 '16 at 01:54
  • Can you give me some advise whether it can be possible to return NULL when key value don't exist just like pymongo does? – Leo Zhao Mar 10 '16 at 02:26

1 Answers1

1

It will Raise [what(): unset document::element] when I try to get key value from documents which exactly don't have those keys.

    using bsoncxx::builder::stream::document;
    using bsoncxx::builder::stream::open_document;
    using bsoncxx::builder::stream::close_document;
    using bsoncxx::builder::stream::open_array;
    using bsoncxx::builder::stream::close_array;
    using bsoncxx::builder::stream::finalize;

    mongocxx::instance inst{};
    mongocxx::client conn{mongocxx::uri{"mongodb://10.9.0.1:27017"}};
    mongocxx::collection collection = conn["wechat"]["article"];

    mongocxx::options::find opts;
    mongocxx::options::count copts;
    document condition, options;

    condition << "$and" << open_array <<
            open_document << "subscribeRobot" << open_document << "$exists" << 1 << close_document << close_document <<
            open_document << "body.title" << open_document << "$exists" << 1 << close_document << close_document <<
            open_document << "body.content" << open_document << "$exists" << 1 << close_document << close_document <<
            close_array;

    options << "subscribeRobot" << 1 << "body.title" << 1 << "body.content" << 1;
    opts.projection(options.view());
    copts.limit(1000);

    mongocxx::cursor cursor = collection.find(condition.view(), opts);
    dociter docbegin = cursor.begin();
    int64_t allartnumber = collection.count(condition.view(), copts);
    cout << allartnumber << endl;

    # pragma omp parallel for
    for(int i = 0; i < allartnumber; i++){
        doc = *(next(docbegin, i));
        wechat = bsoncxx::to_json(doc["subscribeRobot"]);
        title = bsoncxx::to_json(doc["body"]["title"]);
        // It will raise [what():  unset document::element] when these key above don't exists.
    }
Leo Zhao
  • 77
  • 1
  • 12
  • When you call `operator[]`, if the field you are requesting in the document does not exist, then it will return a default constructed (meaning invalid) `element`. An invalid `element` does not have a type, and cannot be passed to the `to_json` function. If you do so, it will throw the given exception, because how can a non-existent element be represented as JSON? – acm Mar 10 '16 at 20:16
  • Also, note that I think there is a subtle flaw with operator[] behaving inconsistently: https://jira.mongodb.org/browse/CXX-862 – acm Mar 10 '16 at 20:55