5

How to query MongoDB database using regex in c++.

mongo-cxx-driver-r3.1.1

hear is include

#include <cstdlib>
#include <iostream>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp>
#include <cstdint>
#include <vector>
#include <mongocxx/stdx.hpp>
#include <bson.h>
#include <conio.h> 
#include <sstream> 
#include <stdio.h> 
#include <string>
#include <bsoncxx/types.hpp>
#include <mongocxx/exception/exception.hpp>
#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>

using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::finalize;
using bsoncxx::builder::stream::open_document;
using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::make_document;

here is what I have tried.

  void MyClass::on_querybtn_clicked()
   {

auto collection = conn["TestDB"]["fdevices"];
bsoncxx::types::b_regex::b_regex();//i am lost here dont know how to use it
auto cursor = collection.find({});

 for (auto doc : cursor) {

QString qstr = QString::fromStdString(bsoncxx::to_json(doc));
QJsonDocument docum = QJsonDocument::fromJson(qstr.toUtf8());
QJsonObject object = docum.object();
QString call = object["Data"].toString();
ui.mqttList->addItem(call);
}
}

Previously I build a software using Java now I am trying to build same software in Qt c++, I am new to c++.

Here is query code that I used in java for Query.

 DBObject query = new BasicDBObject();
 Pattern regex = Pattern.compile("^14-09-2017"); 
 query.put("Data", regex);

here is how my data look like. Database image

acm
  • 12,183
  • 5
  • 39
  • 68
Sam Jamali
  • 77
  • 4

3 Answers3

4

Use some builders and make the document, providing the string input for the pattern:

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

using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::make_document;

auto cursor = collection.find(make_document(
  kvp("Data", bsoncxx::types::b_regex{"^14-09-2017"})
));

A bit easier to read than stream builder IMHO, but the basic premise is there. Still a string for input, much like Pattern.compile()

Neil Lunn
  • 148,042
  • 36
  • 346
  • 317
  • using bsoncxx::builder::basic::make_document; error "bsoncxx::c_noabi::builder::basic" has no member make_document. am i missing something . @NeilLunn – Sam Jamali Nov 01 '17 at 07:19
  • @SamJamali Did you `include`? I suppose I should not have presumed that , so added the include headers to the sample. I presumed you would have already used either the basic or stream builder before – Neil Lunn Nov 01 '17 at 07:28
  • I believe above code will solve the issue, perhaps I am missing a small detail somewhere if I am not mistaken it has to do something with driver version or maybe I am missing some include. bsoncxx::builder::basic::make_document; has no member make_document – Sam Jamali Nov 01 '17 at 08:18
  • @SamJamali Sorry, been busy. If you need a bit more basic guidance, look at the examples on the driver repository: [documentation_examples.cpp](https://github.com/mongodb/mongo-cxx-driver/blob/f3e98ed83f8684670cb29b1a3f004511752d6c34/examples/mongocxx/mongodb.com/documentation_examples.cpp) is a good place to understand general usage. At any rate I would advise using a most recent build. All drivers are about to be updated again anyway, so you do not want to be left far behind by using any earlier version. – Neil Lunn Nov 01 '17 at 08:23
  • 1
    if I am not mistaken make_document method is not included yet in the stable version, but available in the master branch, I had the same issue then I just simply changed my document.hpp file and it works for me, I am not sure if its appropriate way to do it. Take a look here. [link](https://stackoverflow.com/questions/44540858/using-declaration-not-found-in-mongodb-c-driver) – Joyo Waseem Nov 01 '17 at 17:58
2

I've tried several approaches but finally I came up with the most straightforward one. I build a query as a json and then convert is to bson using bsoncxx::from_json function. a working piece of code looks like:

 mongocxx::instance instance{};
 mongocxx::uri uri("mongodb://localhost:27017");
 mongocxx::client *m_c = new mongocxx::client(uri);    
 std::string query = "{\"name.firstName\": {\"$options\": \"i\",\"$regex\": \"^pattern\"}}";
 bsoncxx::builder::stream::document doc;
 //this one to define q not inside try catch block.
 bsoncxx::document::value q(doc.view());
 try{
   q = bsoncxx::from_json(query);

 }catch (bsoncxx::exception &e){
    std::cerr<<"error: "<<e.code()<<" "<<e.what();
    return;
 }
 mongocxx::options::find opt;
 mongocxx::cursor cursor = m_c->database("db_name").collection("collection_name").find( std::move(q), opt);

An important thing here is that I could not use q as bsoncxx::document::view. Because a value for this view is created inside try - catch block, till the time when the control flow came to the find function bsoncxx::document::view q was always empty. So I had to use bsoncxx::document::value q and move semantics in the find function.

Alex
  • 43
  • 5
  • Just an FYI, but if you use C++11 raw string literals you can remove all that escaping from `query`. – acm Apr 19 '18 at 15:40
0
#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>

using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::make_document;

auto cursor =  collection.find(make_document(kvp("field",make_document(kvp("$regex":"pattern"),kvp("$options","i"))));

Refer To Official

CMLDMR
  • 334
  • 2
  • 12