MongoDB:在C#驱动程序中构建查询

5

我遇到了在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);

补充:

上述查询取自我的另一个问题: MongoDB:匹配多个数组元素 欢迎您参与解决。

2个回答

5

如果您想获取确切的查询结果,以下是操作步骤:

// 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)
    });

这里的诡计在于,虽然各种Query方法的许多参数都期望BsonValue而不是查询条件,但你可以通过执行以下操作从Query实例创建一个BsonValue实例:

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

实际发送的查询与您最初的请求完全匹配:
query = {
  "Properties": {
    "$all": [ 
        { "$elemMatch": { "Type": 1, "Value": "a" }}, 
        { "$elemMatch": { "Type": 2, "Value": "b" }}
    ]
  }
}

我之前也从未见过这种$all用法,但显然,它听起来像尚未记录


3

尽管我可以确认你发布的查询在我的机器上运行,但是 $all 的说明似乎表明它不应该接受表达式或查询,而只接受值:

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

(如果允许查询,则文档使用<expression>可与$and进行比较)。因此,C#驱动程序仅接受BsonValue数组而不是IMongoQuery
但是,以下查询应该是等效的:
{
    $and: [
        { "Location": { "$within": { "$center": [ [1, 1], 5 ] } } },
        { "Properties" : { $elemMatch: { "Type": 1, "Value": "a" } } },
        { "Properties" : { $elemMatch: { "Type": 2, "Value": "b" } } }   
    ]
}

这句话在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"))));

使用$and的查询与原始查询并不完全等价。请查看我问题底部的链接了解详情。不管怎样,感谢你的回答。 - Kamarey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接