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 IList <object> GetValues(DynamicObject dynobj, string name) { var vals = (IEnumerable <object>)dynobj.GetMember(name); IList <object> values = new List <object>(); foreach (var val in vals) { values.Add(this.GetValue(val)); } return(values); }
protected DynamicObject Project(DynamicObject projection, IList <string> names) { foreach (var name in projection.GetMemberNames().Where(n => IsTrue(projection.GetMember(n)))) { if (!names.Contains(name)) { names.Add(name); } } if (names.Count == 0 || (names.Count == 1 && names.First() == "Id")) { names = this.GetMemberNames().ToList(); } foreach (var name in projection.GetMemberNames().Where(n => IsFalse(projection.GetMember(n)))) { if (names.Contains(name)) { names.Remove(name); } } DynamicObject document = this.GetEmptyClone(); foreach (var name in names) { document.SetMember(name, this.GetMember(name)); } foreach (var name in projection.GetMemberNames().Where(n => !IsFalse(projection.GetMember(n)) && !IsTrue(projection.GetMember(n)))) { document.SetMember(name, this.Evaluate(projection.GetMember(name))); } return(document); }
public bool Match(DynamicObject document) { foreach (var key in this.values.Keys) { var value = this.values[key]; if (value is DynamicObject) { return(((DynamicObject)value).Match(document, key)); } if (!this.values[key].Equals(document.GetMember(key))) { return(false); } } return(true); }
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); }