5

I stacked to build this Mongodb query in C# driver:

{ 
    Location: { "$within": { "$center": [ [1, 1], 5 ] } },
    Properties: {
        $all: [
            { $elemMatch: { Type: 1, Value: "a" } },
            { $elemMatch: { Type: 2, Value: "b" } }
        ]
    }
}

Something next:

var geoQuery = Query.WithinCircle("Location", x, y, radius);
var propertiesQuery = **?**;
var query = Query.And(geoQuery, propertiesQuery);

Addition:

The above query taken from my another question: MongoDB: Match multiple array elements You are welcome to take part in its solution.

2 Answers 2

5

Here's how if you want to get that exact query:

// create the $elemMatch with Type and Value
// as we're just trying to make an expression here, 
// we'll use $elemMatch as the property name 
var qType1 = Query.EQ("$elemMatch", 
    BsonValue.Create(Query.And(Query.EQ("Type", 1),
                     Query.EQ("Value", "a"))));
// again
var qType2 = Query.EQ("$elemMatch", 
    BsonValue.Create(Query.And(Query.EQ("Type", 2), 
                     Query.EQ("Value", "b"))));
// then, put it all together, with $all connection the two queries 
// for the Properties field
var query = Query.All("Properties", 
    new List<BsonValue> { 
        BsonValue.Create(qType1), 
        BsonValue.Create(qType2)
    });

The sneaky part is that while many of the parameters to the various Query methods expect BsonValues rather than queries, you can create a BsonValue instance from a Query instance by doing something like:

// very cool/handy that this works
var bv = BsonValue.Create(Query.EQ("Type", 1)); 

The actual query sent matches your original request exactly:

query = {
  "Properties": {
    "$all": [ 
        { "$elemMatch": { "Type": 1, "Value": "a" }}, 
        { "$elemMatch": { "Type": 2, "Value": "b" }}
    ]
  }
}

(I'd never seen that style of $all usage either, but apparently, it sounds like it's just not documented yet.)

Sign up to request clarification or add additional context in comments.

Comments

3

While I can confirm that the query you posted works on my machine, the documentation of $all seems to indicate that it shouldn't accept expressions or queries, but only values:

Syntax: { field: { $all: [ <value> , <value1> ... ] }

(The documentation uses <expression> if queries are allowed, compare to $and). Accordingly, the C# driver accepts only an array of BsonValue instead of IMongoQuery.

However, the following query should be equivalent:

{
    $and: [
        { "Location": { "$within": { "$center": [ [1, 1], 5 ] } } },
        { "Properties" : { $elemMatch: { "Type": 1, "Value": "a" } } },
        { "Properties" : { $elemMatch: { "Type": 2, "Value": "b" } } }   
    ]
}

Which translates to the C# driver as

var query = 
Query.And(Query.WithinCircle("Location", centerX, centerY, radius),
Query.ElemMatch("Properties", Query.And(Query.EQ("Type", 1), Query.EQ("Value", "a"))),
Query.ElemMatch("Properties", Query.And(Query.EQ("Type", 2), Query.EQ("Value", "b"))));

1 Comment

The query with $and is not 100% equivalent to the original one. Please see the link at bottom of my question for details. Anyway thanks for your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.