我正在尝试生成一个查询,查找成本大于3的所有大型红色事物。
这个查询似乎就是我所追求的:
{ "color" : "red", "size" : "large", "cost" : { "$gt" : 3.0 } }
但是,我无法找到使用官方MongoDB CSharp驱动程序创建成本条件的优雅方法。这是一个似乎创建查询的hack:
QueryConditionList gt = Query.GT("cost", BsonDouble.Create(3));
QueryDocument query = new QueryDocument();
query.Add("color", "red");
query.Add("size", "large");
query.Add(gt.ToBsonDocument().Elements);
List<BsonDocument> results = events.Find(query).ToList();
另一种似乎有用的方法就是这样:
QueryDocument query = new QueryDocument();
query.Add("color", "red");
query.Add("size", "large");
query.Add("cost", new BsonDocument("$gt", BsonDouble.Create(3)));
List<BsonDocument> results = events.Find(query).ToList();
这些方法中的任何一种都是实现这一目标的好方法吗?还有另一个吗?
我需要使用允许我动态构建查询并添加将在查询中涉及的字段的技术。我希望找到一种通过query.Add()添加条件的方法,但我不知道这是否可行。
感谢任何帮助。
答案 0 :(得分:6)
您可以使用“查询”构建器,如下所示:
var query = Query.And(
Query.EQ("color", "red"),
Query.EQ("size", "large"),
Query.GT("cost", 3)
);
更新抱歉,我现在看到你在问什么。
你也可以这样做:
int i = 0;
var qc = QueryComplete[3];
qc[i++] = Query.EQ("color", "red");
qc[i++] = Query.EQ("size", "large");
qc[i++] = Query.GT("cost", 3);
var query = Query.And(qc);
这样,您仍然可以使用构建器方法并使其具有动态性。
答案 1 :(得分:2)
您可以以强力方式对数据进行驱动,只需构建一个“QueryElement”树并调用BuildQuery以递归方式构建它,就像在此示例类中一样:
public class QueryElement
{
public enum eOperator
{
AND, OR, EQ, NE, GT, GTE, LT, LTE //etc.
};
public eOperator Operator { get; set; }
public string Field { get; set; }
public BsonValue Value { get; set; }
public List<QueryElement> Children { get; set; }
public IMongoQuery BuildQuery()
{
int i = 0;
var qc = new IMongoQuery[(Children!=null)?Children.Count:0];
if (Children != null)
{
foreach (var child in Children)
{
qc[i++] = child.BuildQuery();
}
}
switch (Operator)
{
// multiple element operators
case eOperator.AND:
return Query.And(qc);
case eOperator.OR:
return Query.And(qc);
// single element operators
case eOperator.EQ:
return Query.EQ(Field, Value);
case eOperator.NE:
return Query.NE(Field, Value);
case eOperator.GT:
return Query.GT(Field, Value);
case eOperator.GTE:
return Query.GTE(Field, Value);
case eOperator.LT:
return Query.LT(Field, Value);
case eOperator.LTE:
return Query.LTE(Field, Value);
}
return null;
}
}