我堆积在C#驱动程序中构建这个Mongodb查询:
{
Location: { "$within": { "$center": [ [1, 1], 5 ] } },
Properties: {
$all: [
{ $elemMatch: { Type: 1, Value: "a" } },
{ $elemMatch: { Type: 2, Value: "b" } }
]
}
}
下一步:
var geoQuery = Query.WithinCircle("Location", x, y, radius);
var propertiesQuery = **?**;
var query = Query.And(geoQuery, propertiesQuery);
增加:
以上查询来自我的另一个问题: MongoDB: Match multiple array elements 欢迎您参与其解决方案。
答案 0 :(得分: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
而不是查询,但您可以从BsonValue
创建Query
个实例例如:
// 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
用法的风格,但显然,它听起来像it's just not documented。)
答案 1 :(得分:3)
虽然我可以确认您发布的查询在我的计算机上有效,但documentation of $all
似乎表示不应接受表达式或查询,但只有值:
Syntax: { field: { $all: [ <value> , <value1> ... ] }
(如果允许查询,则文档使用<expression>
compare to $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"))));