2

I have read the MongoDB documentation and there is a "$regex" operator. I'm currently doing a NodeJS binding for a driver written in C++ that use bsonsearch. I use this code in NodeJS :

db.find(bson.serialize({foo: {$regex: new RegExp('.', 'i')}}), function (err, docs) {
  //things
});

It goes through C++ and it get processed by mongoc-matcher. But mongoc-matcher return me an error on this :

Invalid operator "$regex"

So, I searched for alternative and I see this works :

db.find(bson.serialize({foo: {$eq: new RegExp('.', 'i')}}), function (err, docs) {
  //things
});

But I need to deal with the $regex operator for backwards compatibily problems. Anyone have the right syntax ?

  • 1) Your alternative looks similar to the original, is that an error in posting? 2) Which `mongoc-matcher` are you referring to ? 3) Which version of MongoDB C driver are you using ? – Wan B. Oct 09 '18 at 04:36
  • 1
    @WanBachtiar 1) I edited my alternative code sorry... I need to use `$regex` and not `$eq new RegExp()` for backwards compatibility. 2 - 3) I use this version with `bsoncompare` : https://github.com/bauman/bsonsearch/tree/d44390570e4e1d4421e4a48049e66be3dd291da2/lib Thanks a lot for taking time to help me – Aurélien Foucault Oct 09 '18 at 08:25
  • Seems that @baumann.space, the author of `bsonsearch` using has beaten me to it. ;) – Wan B. Oct 09 '18 at 22:46
  • @WanBachtiar I'm not sure this question is related to bsonsearch. As written, db.find(...) is a nodejs/mongodb question. I have limited knowledge there. The error OP is getting looks like a node.js elevated error – bauman.space Oct 10 '18 at 14:21

1 Answers1

0

oh hi, I am the author of bsonsearch!

edit- Opened a room to discuss https://chat.stackoverflow.com/rooms/181623/bsonsearch

edit2: it looks like you're trying to use extended JSON with $regex but encoding to BSON bits. We'll need to pick one or the other and use the appropriate bson_new_from_* on the C side to deserialize it.

My code doesn't really have anything to do with mongo-c-driver other than using some of their code. It's a separate project intended for client-side document matching.

Assuming you know that and are not trying to connect bsoncompare to mongodb, you'll need to use mongodb's binary regex format directly in the string if you intend to use it that way.

bsonsearch regex shcema comes directly from mongodb regex schema (splitting $regex from $options) https://docs.mongodb.com/manual/reference/operator/query/regex/

This test file has examples https://github.com/bauman/bsonsearch/blob/master/lib/tests/bsoncompare_regex.c

for your specific case, use this:

spec = {"foo": {"$regex": ".", "$options": "i"}}
                           ^                ^
---------------------------^                ^
--------------------------------------------^ (case insensitive)

put the utf-8 string you want to use as your regex directly in the $regex key(a dot in your case) and add an $options key with for case insensitivity (with an i for case insensitive)

You probably know this, but a . simply matches exactly one character, anywhere in a string.

https://www.debuggex.com/cheatsheet/regex/pcre

bauman.space
  • 1,993
  • 13
  • 15
  • 1
    Nice to see you there !! When I tried your syntax it send me the same error : `AssertionError [ERR_ASSERTION]: 'Invalid operator "$regex"' == null`. I have write this : `db.find(bson.serialize({foo: {"$regex": ".", "$options": "i"}}), function (err, docs) {});` – Aurélien Foucault Oct 10 '18 at 12:15
  • db.find(...) looks like a mongodb function. Are you working working with mongodb or bsonsearch? – bauman.space Oct 10 '18 at 13:49
  • If mongodb, try removing the BSON.serialize - make it `...db.find({foo: {"$regex": ".", "$options": "i"}})` – bauman.space Oct 10 '18 at 13:55
  • 1
    db.find is a binding made by myself to call C++ code. Which call `mongoc-matcher` functions in `bsonsearch` such as `mongoc_matcher_match()` or `mongoc_matcher_new()`. The error comme from those functions – Aurélien Foucault Oct 10 '18 at 14:28
  • very cool. Is the binding open source? You should be calling functions similar to the python binding. There are helpers in the bsoncompare.c that can take a character string and cast into a libbson – bauman.space Oct 10 '18 at 16:01
  • clearing it up, you did something similar to this function? make a new bson object from json using `bson_new_from_json` and passing that object to `_matcher_new` ? https://github.com/bauman/bsonsearch/blob/master/lib/bsoncompare.c#L230-L240 – bauman.space Oct 10 '18 at 16:13
  • opened a room to avoid spamming chat - https://chat.stackoverflow.com/rooms/181623/bsonsearch – bauman.space Oct 10 '18 at 16:27
  • 1
    I don't have enough reputation to speak in that room :/ . It's not open source for the moment :/ . I mka emy bson from bson_seralize in JS and I get it with V8 in my C++ code and I use `bson_new_from_data()` to build a bson_t structure. – Aurélien Foucault Oct 11 '18 at 07:57
  • {$regex: ...} is Extended JSON, not valid BSON., if you're doing `bson_new_from_data`, your node.js code should be `db.find(bson.serialize({"foo": new RegEx(".", "i")}))` if you need to use use $regex explicity, you need to `db.find(json.dumps({"foo": {$regex: ".", $options: "i")}}))` and use `bson_new_from_json` on the c++ side --- https://docs.mongodb.com/manual/reference/mongodb-extended-json/ – bauman.space Oct 11 '18 at 13:53
  • Any luck on either method? – bauman.space Oct 16 '18 at 16:50
  • Use `json` makes a lot of change in our code and it's not a real priority. So I will make it later. Sorry about it :/ – Aurélien Foucault Oct 16 '18 at 20:54
  • no worries, you tried `db.find(bson.serialize({"foo": new RegEx(".", "i")}))` on your node side ... omitting the "$regex" and that didn't work? – bauman.space Oct 17 '18 at 17:02
  • I finally implement $regex in mongoc-matche as an operator and it works like a charm. – Aurélien Foucault Oct 30 '18 at 09:57
  • glad it worked! feed free to flag issues you find on the project page if needed – bauman.space Oct 30 '18 at 18:46