Remove an element from an existing bsoncxx document

536 views
Skip to first unread message

Rustam Abdullaev

unread,
Dec 15, 2017, 10:30:24 AM12/15/17
to mongodb-user
I have a bsoncxx document that I need to clone except for its _id (ObjectId).

How can I do that?

The following does not work:

    bsoncxx::document::value clone(bsoncxx::document::view doc)
    {
      bsoncxx::builder::stream::document builder;
      for (auto& el : doc) {
        if (el.type != bsoncxx::type::k_oid) {
          builder << el.key() << el;
        }
      }
      return builder << finalize;
    }



Andrew Morrow

unread,
Dec 15, 2017, 10:54:44 AM12/15/17
to mongod...@googlegroups.com

Hi -

I wouldn't use the stream builder for that, it really isn't designed for that sort of work. Try using the basic builder instead:

    bsoncxx::document::value clone(bsoncxx::document::view doc)
    {
      bsoncxx::builder::basic::document builder;

      for (auto& el : doc) {
        if (el.type != bsoncxx::type::k_oid) {
          builder.append(kvp(el.key(), el.value()));
        }
      }
      return builder.extract();
    }

You could also generalize this a bit:

    template<typename Predicate>
    bsoncxx::document::value filter(bsoncxx::document::view doc, const Predicate& predicate)
    {
      bsoncxx::builder::basic::document builder;
      for (auto& el : doc) {
        if (!predicate(el)) {
          builder.append(kvp(el.key(), el.value()));
        }
      }
      return builder.extract();
    }


Then you could call it like:

bsoncxx::document::value doc = ...
auto id_filtered = filter(doc, [](const auto& el) { return el.type == bsoncxx::type::k_oid; });

Above code is untested but should get across the idea.

Thanks,
Andrew


--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: https://docs.mongodb.com/manual/support/
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user+unsubscribe@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at https://groups.google.com/group/mongodb-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/mongodb-user/a60e9db2-ef73-4f59-9bd9-f2be025fa140%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rustam

unread,
Dec 15, 2017, 11:26:31 AM12/15/17
to mongod...@googlegroups.com
That doesn't work.

error C2039: 'value': is not a member of 'bsoncxx::v_noabi::document::element'

You received this message because you are subscribed to a topic in the Google Groups "mongodb-user" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mongodb-user/_st68QCIxDo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mongodb-user+unsubscribe@googlegroups.com.

To post to this group, send email to mongod...@googlegroups.com.
Visit this group at https://groups.google.com/group/mongodb-user.

Andrew Morrow

unread,
Dec 15, 2017, 11:50:03 AM12/15/17
to mongod...@googlegroups.com
Message has been deleted

Andrew Morrow

unread,
Dec 15, 2017, 4:29:40 PM12/15/17
to mongod...@googlegroups.com


Here is a complete example:

#include <cstdlib>
#include <iostream>

#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/types.hpp>
#include <bsoncxx/types/value.hpp>
#include <bsoncxx/json.hpp>

template<typename Predicate>
bsoncxx::document::value filter(bsoncxx::document::view doc, const Predicate& predicate) {
    using namespace bsoncxx::builder;

    basic::document builder;
    for (auto& el : doc) {
        if (!predicate(el)) {
            builder.append(basic::kvp(el.key(), el.get_value()));
        }
    }
    return builder.extract();
}

int main(int, char**) {

    using namespace bsoncxx::builder;
 
    auto doc_builder = basic::document{};

    doc_builder.append(basic::kvp("foo", "bar"));
    doc_builder.append(basic::kvp("baz", bsoncxx::types::b_bool{false}));
    doc_builder.append(basic::kvp("garply", bsoncxx::types::b_double{3.14159}));
    auto doc = doc_builder.extract();

    std::cout << "Original: " << bsoncxx::to_json(doc) << std::endl;

    auto doc_filtered = filter(
        doc.view(), [](const bsoncxx::document::element& el) {
            return el.key() == "foo";
    });
    std::cout << "Filtered: " << bsoncxx::to_json(doc_filtered) << std::endl;

    return EXIT_SUCCESS;
}

Running it gives:

Original: { "foo" : "bar", "baz" : false, "garply" : 3.1415899999999998826 }
Filtered: { "baz" : false, "garply" : 3.1415899999999998826 }

On Fri, Dec 15, 2017 at 3:43 PM, Rustam Abdullaev <rust...@gmail.com> wrote:
No luck:

error C2664: 'void bsoncxx::v_noabi::builder::basic::sub_document::append_(bsoncxx::v_noabi::builder::concatenate_doc)': cannot convert argument 1 from 'boost::string_view' to 'bsoncxx::v_noabi::builder::concatenate_doc'
note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
note: see reference to function template instantiation 'void bsoncxx::v_noabi::builder::basic::sub_document::append<boost::string_view,bsoncxx::v_noabi::types::value>(Arg &&,bsoncxx::v_noabi::types::value &&)' being compiled

--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: https://docs.mongodb.com/manual/support/
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user+unsubscribe@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at https://groups.google.com/group/mongodb-user.
Reply all
Reply to author
Forward
0 new messages