1

I want to create and run a query using MongoDB C++ api having these conditions :

  1. timestamp is within a range AND
  2. From an array of strings, atleast one of them to be equal to the type

I have these fields in my MongoDB document: id_, timestamp, type

I have used builder stream to create my query. For the first condition to filter timestamp I did :

Document doc_timestamp;
doc_timestamp << "timestamp" << open_document <<
    "$gt" << startTS <<
    "$lte" << endTS
  << close_document

If I run the first condition alone, it runs perfectly. But I am not sure how to do it for type field. I did like this:

Document doc_type;
auto arr_type = doc_type <<
"$or" << open_array;
for (auto nNum : nTypes) {
    arr_type = arr_type << "type" << std::to_string(nNum);
}
arr_type << close_array;

This filter does not work. It throws a run time error. What is wrong I am doing here? Also, how do I concatenate these two filter and pass it the find function to run the query.

Thanks in advance!

Anupam
  • 49
  • 8

1 Answers1

2

Not sure if the $or is the best option for the array filter. If you want to find if an element is present in an array you can use the $in operator

There have been some discussions about building a bson array in a loop like how you tried, but even @acm suggested there to use the bsoncxx::builder::basic instead of bsoncxx::builder::stream. With bsoncxx::builder::basic::array{} you can append all the types to the array and use it directly in the query with the $in operator.

Regarding how to concatenate both filters, they can just be added one after the other:

using namespace bsoncxx::builder::stream;

// Some random start/end time and types
std::chrono::system_clock::time_point from_time = std::chrono::system_clock::now() - std::chrono::hours(5);
std::chrono::system_clock::time_point to_time = std::chrono::system_clock::now() + std::chrono::hours(5);
const auto types = { "xls", "docx", "pdf" };

auto array_builder = bsoncxx::builder::basic::array{};
for (const auto& type : types ) { array_builder.append(type); }

mongocxx::cursor cursor = db["query"].find(
    document{} <<
        "timestamp" << open_document <<
                            "$gt" << bsoncxx::types::b_date{ from_time } <<
                            "$lt" << bsoncxx::types::b_date{ to_time } <<
                       close_document <<
        "type"      << open_document  <<
                            "$in" << array_builder <<
                       close_document <<
    finalize
);

for (auto doc : cursor) {
    std::cout << bsoncxx::to_json(doc) << std::endl;
}
SPM
  • 405
  • 1
  • 5
  • 16