MongoDB:在c#驱动中构建查询

时间:2021-04-14 03:03:27

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

我堆叠在c#驱动中构建这个Mongodb查询:

{ 
    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.

上面的查询来自我的另一个问题:MongoDB:匹配多个数组元素,欢迎您参与它的解决方案。

2 个解决方案

#1


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:

sneaky部分是,虽然各种查询方法的许多参数都期望BsonValues而不是查询,但您可以通过以下方法创建一个BsonValue实例:

// 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.)

(我也没见过那种$all用法的风格,但显然,它听起来还没有被记录下来。)

#2


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:

虽然我可以确认您发布的查询在我的机器上有效,但是$all的文档似乎表明它不应该接受表达式或查询,而应该只接受值:

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.

(如果允许查询,文档使用 ,与$and相比)。因此,c#驱动程序只接受一个BsonValue数组,而不接受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

将c#驱动程序转换为

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


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:

sneaky部分是,虽然各种查询方法的许多参数都期望BsonValues而不是查询,但您可以通过以下方法创建一个BsonValue实例:

// 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.)

(我也没见过那种$all用法的风格,但显然,它听起来还没有被记录下来。)

#2


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:

虽然我可以确认您发布的查询在我的机器上有效,但是$all的文档似乎表明它不应该接受表达式或查询,而应该只接受值:

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.

(如果允许查询,文档使用 ,与$and相比)。因此,c#驱动程序只接受一个BsonValue数组,而不接受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

将c#驱动程序转换为

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"))));