public IEnumerable <DynamicObject> Aggregate(DynamicObject spec = null) { DynamicObject query = null; DynamicObject projection = null; if (spec != null && spec.Exists("$match")) { query = (DynamicObject)spec.GetMember("$match"); } if (spec != null && spec.Exists("$project")) { projection = (DynamicObject)spec.GetMember("$project"); } IEnumerable <DynamicObject> result = this.Find(query, projection); if (spec != null && spec.Exists("$skip")) { int n = (int)spec.GetMember("$skip"); result = result.Skip(n); } if (spec != null && spec.Exists("$limit")) { int n = (int)spec.GetMember("$limit"); result = result.Take(n); } if (spec != null && spec.Exists("$sort")) { DynamicObject sspec = (DynamicObject)spec.GetMember("$sort"); string[] fldnames = sspec.GetMemberNames().ToArray(); List <int> orders = new List <int>(); foreach (var fldname in fldnames) { orders.Add((int)sspec.GetMember(fldname) < 0 ? -1 : 1); } int[] fldorders = orders.ToArray(); return(result.OrderBy(dobj => dobj, new DynamicObjectComparer(fldnames, fldorders))); } return(result); }
private bool Match(DynamicObject dynobj, string name) { var value = dynobj.GetMember(name); foreach (var key in this.values.Keys) { if (key == "$exists") { if (!dynobj.Exists(name).Equals(this.GetMember(key))) { return(false); } else { continue; } } if (key == "$lt") { if (!(((IComparable)value).CompareTo(this.EvaluateMember(key)) < 0)) { return(false); } else { continue; } } if (key == "$lte") { if (!(((IComparable)value).CompareTo(this.EvaluateMember(key)) <= 0)) { return(false); } else { continue; } } if (key == "$gt") { if (!(((IComparable)value).CompareTo(this.EvaluateMember(key)) > 0)) { return(false); } else { continue; } } if (key == "$gte") { if (!(((IComparable)value).CompareTo(this.EvaluateMember(key)) >= 0)) { return(false); } else { continue; } } if (key == "$ne") { if (value.Equals(this.EvaluateMember(key))) { return(false); } else { continue; } } if (key == "$eq") { if (!value.Equals(this.EvaluateMember(key))) { return(false); } else { continue; } } if (key == "$in") { if (!((IList)this.GetMember(key)).Contains(value)) { return(false); } else { continue; } } if (key == "$nin") { if (((IList)this.GetMember(key)).Contains(value)) { return(false); } else { continue; } } if (key == "$not") { if (((DynamicObject)this.GetMember(key)).Match(dynobj, name)) { return(false); } else { continue; } } if (key == "$or") { bool result = false; foreach (var dobj in (IEnumerable <DynamicObject>) this.GetMember(key)) { if (dobj.Match(dynobj, name)) { result = true; break; } } if (!result) { return(false); } continue; } if (key == "$nor") { foreach (var dobj in (IEnumerable <DynamicObject>) this.GetMember(key)) { if (dobj.Match(dynobj, name)) { return(false); } } continue; } if (key == "$and") { foreach (var dobj in (IEnumerable <DynamicObject>) this.GetMember(key)) { if (!dobj.Match(dynobj, name)) { return(false); } } continue; } if (key == "$type") { Type type = (Type)this.GetMember(key); if (!type.IsInstanceOfType(value)) { return(false); } continue; } throw new InvalidOperationException(string.Format("Invalid operator '{0}'", key)); } return(true); }