Operators

The following is a list of the available query operators for the Mangrove query builder. This page follows the structure of the MongoDB query operator documentation .

Comparison Operators

The following operators can be expressed using built-in C++ operators such as < and !=. They work on any field type, and the right-hand value must be the same type as the field. Free functions are also provided in the mangrove namespace that can be used in lieu of the overloaded operators.

  • $eq

    // { age: {$eq: 21} }
    auto results = User::find(MANGROVE_KEY(User::age) == 21);
    auto results = User::find(mangrove::eq(MANGROVE_KEY(User::age), 21));
    
  • $gt

    // { age: {$gt: 21} }
    auto results = User::find(MANGROVE_KEY(User::age) > 21);
    auto results = User::find(mangrove::gt(MANGROVE_KEY(User::age), 21));
    
  • $gte

    // { age: {$gte: 21} }
    auto results = User::find(MANGROVE_KEY(User::age) >= 21);
    auto results = User::find(mangrove::gte(MANGROVE_KEY(User::age), 21));
    
  • $lt

    // { age: {$lt: 21} }
    auto results = User::find(MANGROVE_KEY(User::age) < 21);
    auto results = User::find(mangrove::lt(MANGROVE_KEY(User::age), 21));
    
  • $lte

    // { age: {$lte: 21} }
    auto results = User::find(MANGROVE_KEY(User::age) <= 21);
    auto results = User::find(mangrove::lte(MANGROVE_KEY(User::age), 21));
    
  • $ne

    // { age: {$ne: 21} }
    auto results = User::find(MANGROVE_KEY(User::age) != 21);
    auto results = User::find(mangrove::ne(MANGROVE_KEY(User::age), 21));
    

The following operators are provided as member functions of the fields which are returned from the MANGROVE_KEY and other macros. If the field is a scalar, then the given right hand side must be an array containing the same type. If the field is an array, then the given right hand side must be a similar array, containing the same type.

  • $in

    // { age: {$in: [16, 18, 21]} }
    int ages = std::vector<int>{16, 18, 21}
    auto results = User::find(MANGROVE_KEY(User::age).in(ages));
    
  • $nin

    // { age: {$nin: [16, 18, 21]} }
    int ages = std::vector<int>{16, 18, 21}
    auto results = User::find(MANGROVE_KEY(User::age).nin(ages));
    

Logical Operators

The $or and $and operators can be used to chain different sub-queries together. When using both at once, the && and || follow their usual C++ precedence rules.

  • $or

    // { $or: [ {age: {$gt: 65}}, {age: {$lt: 5}} ] }
    auto results = User::find((MANGROVE_KEY(User::age) > 65 || MANGROVE_KEY(User::age) < 5));
    
  • $and

    // { $and: [ {age: {$gt: 65}}, {age: {$lt: 5}} ] }
    auto results = User::find((MANGROVE_KEY(User::age) > 65 && MANGROVE_KEY(User::age) < 5));
    
  • $not

    The $not operator is applied to individual comparisons (as opposed to boolean expressions using the above operators). The C++ ! operator is used for this.

     // { age: {$not: {$lt: 21}} }
     auto results = User::find(!(MANGROVE_KEY(User::age) < 21));
    
  • $nor

    The $nor operator behaves similarly to the $and and $or operators, except that there is no built-in C++ NOR operator. As such, it is provided as a free function that takes a list of query expressions.

     // { $nor: [ {age: {$gt: 65}}, {age: {$lt: 5}} ] }
     auto results = User::find(mangrove::nor(MANGROVE_KEY(User::age) > 65, MANGROVE_KEY(User::age) < 5));
    

Element Operators

  • $exists

    The $exists operator is provided as a member function on fields that takes a boolean argument. It is only enabled for optional fields.

    // { age: {$exists: true} }
    auto results = User::find(MANGROVE_KEY(User::age).exists(true));
    
  • The $type operator is not currently available in the Mangrove query builder, since to work with serialization, the types of fields must correspond to the type defined in the C++ class.

Evaluation Operators

  • $mod

    This operator is provided as a member function on fields, and accepts two parameters: a divisor and a remainder. It is only enabled for fields with numeric types.

    // { age: {$mod: {$divisor: 10, $remainder: 3}} }
    auto results = User::find(MANGROVE_KEY(User::age).mod(10, 3));
    
  • $regex

    This operator is provided as a member function on fields, and accepts two parameters: a regex string and an options string. It is only enabled for string fields.

    // Match users who live on a numbered street, like "14th st.":
    // { "addr.street": {$regex: "\d+th st\.?", $options: "i"} }
    auto results = User::find(MANGROVE_CHILD(User, addr, street).regex("\\d+th st\\.?", "i"));
    
  • $text

    This operator performs a search on a text index in the database. It is provided as a free function that accepts a text query as a string, as well as the optional language, case_sensitive, and diacritic_sensitive parameters as per the MongoDB documentation. These parameters can be passed in as optional values, or specified using “fluent” setter functions:

    // {
    //   $text:
    //     {
    //       $search: "boulevard",
    //       $language: "en",
    //       $caseSensitive: false,
    //       $diacriticSensitive: false
    //     }
    // }
    auto results = User::find(mangrove::text("boulevard").language("en")
                                                         .case_sensitive(false)
                                                         .diacritic_sensitive(false));
    

There are restrictions on the syntax of the $text operator that Mangrove does not check. Refer to the MongoDB documentation to make sure that the $text operator is being used correctly. Also, fields must be text-indexed for the $text operator to work on them.

  • $where

    Mangrove does not provide a $where operator.

Geospational Operators

Mangrove does not currently support geospatial operators, although support is planned in the future, along with a dedicated GeoJSON C++ data type.

Array Operators

For the following code samples, assume that a User has a field scores, which contains an array of integers.

  • $all

    This operator is provided as a member function on fields. It accepts an array of values that are the same type as the elements of the field’s array. This is only enabled for fields which are iterable (i.e. arrays).

    // { scores: {$all: [100, 500, 1000]} }
    auto results = User::find(MANGROVE_KEY(User::scores).all(std::vector<int>{100, 500, 1000}));
    
  • $elemMatch

    This operator accepts a query, and returns documents if the elements inside a field’s array match the given queries. The queries can be constructed in Mangrove using the same syntax as top-level queries.

    For instance, if a User document contains a field past_homes, which is an array of addresses, one could query it like so:

    // Find users that have lived, at some point, in Maryland.
    // { past_homes: {$elemMatch: {state: "MD"}} }
    auto results = User::find(MANGROVE_KEY(User::past_homes).elem_match(MANGROVE_KEY(Address::state) == "MD"));
    

    Using $elemMatch on scalar arrays is a bit tricky, since the scalars don’t have field names to refer to. Instead, one uses the MANGROVE_KEY_ELEM(...) macro to create a field object that refers to the elements of an array. (The equivalent for MANGROVE_CHILD is MANGROVE_CHILD_ELEM.) One can also use MANGROVE_KEY(...).element() and MANGROVE_CHILD(...).element(), respectively.

    // Find users with a score greater than 9000.
    // { scores: {$elemMatch: {$gt: 9000}} }
    
    // The following are equivalent:
    auto results = User::find(MANGROVE_KEY(User::scores).elem_match(MANGROVE_KEY_ELEM(User::score) > 9000));
    results = User::find(MANGROVE_KEY(User::scores).elem_match(MANGROVE_KEY(User::score).element() > 9000));
    

When specifying conditions on the fields of documents in an array in the $elemMatch operator, the fields are referred to as top-level fields. In the example above, the state field is used as MANGROVE_KEY(Adress::state), as opposed to MANGROVE_CHILD(User, past_homes, state). This mirrors the syntax of MongoDB queries themselves. The equivalent BSON would refer to the state field simply as state, not "past_homes.state".

Mangrove does not check if you use .element() or MANGROVE_KEY_ELEM outside of elem_match(...). This will cause a runtime error when the MongoDB server receives an invalid query.

  • $size

    This operator is provided as a member function on fields. It accepts a single argument, which is the array size to check. The operator is only enabled for fields which are iterable (i.e. arrays).

    // { scores: {$size: 10} }
    auto results = User::find(MANGROVE_KEY(User::scores).size(10));
    

Bitwise Operators

The following operators query for documents using bit operations on fields. Each operator has two versions: one that accepts a single mask, either as an integer or a BSON b_binary type, and another that takes a variadic number of bit positions as unsigned integers.

These operators are only enabled for integral or b_binary types.

For the following examples, assume that the User class has an integer field bitvector that represents a set of bits that we want to do bitwise operations on.

  • $bitsAllSet

    // We want to compare the `bitvector` field with the value 0b00010101.
    // The following two queries are equivalent:
    
    // { scores: {$bitsAllSet: 21} }
    auto results = User::find(MANGROVE_KEY(User::bitvector).bitsAllSet(21));
    // { scores: {$bitsAllSet: [0, 2, 4]} }
    auto results = User::find(MANGROVE_KEY(User::bitvector).bitsAllSet(0, 2, 4));
    
  • $bitsAnySet

    // We want to compare the `bitvector` field with the value 0b00010101.
    // The following two queries are equivalent:
    
    // { scores: {$bitsAnySet: 21} }
    auto results = User::find(MANGROVE_KEY(User::bitvector).bitsAnySet(21));
    // { scores: {$bitsAnySet: [0, 2, 4]} }
    auto results = User::find(MANGROVE_KEY(User::bitvector).bitsAnySet(0, 2, 4));
    
  • $bitsAllClear

    // We want to compare the `bitvector` field with the value 0b00010101.
    // The following two queries are equivalent:
    
    // { scores: {$bitsAllClear: 21} }
    auto results = User::find(MANGROVE_KEY(User::bitvector).bitsAllClear(21));
    // { scores: {$bitsAllClear: [0, 2, 4]} }
    auto results = User::find(MANGROVE_KEY(User::bitvector).bitsAllClear(0, 2, 4));
    
  • $bitsAnyClear

    // We want to compare the `bitvector` field with the value 0b00010101.
    // The following two queries are equivalent:
    
    // { scores: {$bitsAnyClear: 21} }
    auto results = User::find(MANGROVE_KEY(User::bitvector).bitsAnyClear(21));
    // { scores: {$bitsAnyClear: [0, 2, 4]} }
    auto results = User::find(MANGROVE_KEY(User::bitvector).bitsAnyClear(0, 2, 4));