I'm trying to generate a query that finds all large, red things with a cost greater than 3.
This query seems to be what I'm after:
{ "color" : "red", "size" : "large", "cost" : { "$gt" : 3.0 } }
But, I am unable to find an elegant way to create the cost condition using the official MongoDB CSharp Driver. This is one hack which seems to create the query:
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();
Another way to do it which seems to work is like this:
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();
Are either of these approaches a good way to accomplish this? Is there another?
I need to use techniques which allow me to dynamically build the query and add fields that will be involved in the query. I was hoping to find a way to add a condition via query.Add( ) but I don't know if that is possible.
Any help is appreciated.
You can use the Query builder throughout, like so:
var query = Query.And(
Query.EQ("color", "red"),
Query.EQ("size", "large"),
Query.GT("cost", 3)
);
update Sorry, I see what you're asking, now.
You could do something like this, also:
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);
This way, you can still use the builder methods and have it be dynamic.
You can data drive it in a brute force manner, just build a tree of "QueryElement" and call BuildQuery to recursively build it as in this example class:
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With