我如何与C#和MongoDB’和’多个$ elemMatch子句?

我使用10Gen认可的c#驱动程序用于mongoDB用于ac#应用程序和数据浏览我正在使用Mongovue。

以下是两个示例文档架构:

{ "_id": { "$oid": "4ded270ab29e220de8935c7b" }, "Relationships": [ { "RelationshipType": "Person", "Attributes": { "FirstName": "Travis", "LastName": "Stafford" } }, { "RelationshipType": "Student", "Attributes": { "GradMonth": "", "GradYear": "", "Institution": "Test1", } }, { "RelationshipType": "Staff", "Attributes": { "Department": "LIS", "OfficeNumber": "12", "Institution": "Test2", } } ] }, { "_id": { "$oid": "747ecc1dc1a79abf6f37fe8a" }, "Relationships": [ { "RelationshipType": "Person", "Attributes": { "FirstName": "John", "LastName": "Doe" } }, { "RelationshipType": "Staff", "Attributes": { "Department": "Dining", "OfficeNumber": "1", "Institution": "Test2", } } ] } 

我需要一个查询来确保满足$ elemMatch标准,以便我可以匹配第一个文档,但不能匹配第二个文档。 以下查询适用于Mongovue。

 { 'Relationships': { $all: [ {$elemMatch: {'RelationshipType':'Student', 'Attributes.Institution': 'Test1'}}, {$elemMatch: {'RelationshipType':'Staff', 'Attributes.Institution': 'Test2'}} ]} } 

如何在我的c#代码中执行相同的查询?

无法使用c#驱动程序构建上述查询(至少在版本1.0中)。

但是你可以构建另一个更清晰的查询,它将返回相同的结果:

 { "Relationships" : { "$elemMatch" : { "RelationshipType" : "Test", "Attributes.Institution" : { "$all" : ["Location1", "Location2"] } } } } 

来自c#的相同查询:

 Query.ElemMatch("Relationships", Query.And( Query.EQ("RelationshipType", "Test"), Query.All("Attributes.Institution", "Location1", "Location2"))); 

一个简单的解决方案是将多个IMongoQuery串在一起,然后将它们与Query.And结束:

 List build = new List(); build.Add(Query.ElemMatch("Relationships", Query.EQ("RelationshipType", "Person"))); var searchQuery = String.Format("/.*{0}.*/", "sta"); build.Add(Query.ElemMatch("Relationships", Query.Or(Query.EQ("Attributes.FirstName", new BsonRegularExpression(searchQuery)), Query.EQ("Attributes.LastName", new BsonRegularExpression(searchQuery))))); var _main = Query.And(build.ToArray()); var DB = MongoDatabase.Create("UrlToMongoDB"); DB.GetCollection("nameOfCollectionInMongoDB").FindAs(_main).ToList(); 

`

我通过构造一组允许生成以下查询的类来解决当前问题:

 { 'Relationships': { $all: [ {$elemMatch: {'RelationshipType':'Student', 'Attributes.Institution': 'Test1'}}, {$elemMatch: {'RelationshipType':'Staff', 'Attributes.Institution': 'Test2'}} ] } } 

以下是类定义:

 class MongoQueryAll { public string Name { get; set; } public List QueryElements { get; set; } public MongoQueryAll(string name) { Name = name; QueryElements = new List(); } public override string ToString() { string qelems = ""; foreach (var qe in QueryElements) qelems = qelems + qe + ","; string query = String.Format(@"{{ ""{0}"" : {{ $all : [ {1} ] }} }}", this.Name, qelems); return query; } } class MongoQueryElement { public List QueryPredicates { get; set; } public MongoQueryElement() { QueryPredicates = new List(); } public override string ToString() { string predicates = ""; foreach (var qp in QueryPredicates) { predicates = predicates + qp.ToString() + ","; } return String.Format(@"{{ ""$elemMatch"" : {{ {0} }} }}", predicates); } } class MongoQueryPredicate { public string Name { get; set; } public object Value { get; set; } public MongoQueryPredicate(string name, object value) { Name = name; Value = value; } public override string ToString() { if (this.Value is int) return String.Format(@" ""{0}"" : {1} ", this.Name, this.Value); return String.Format(@" ""{0}"" : ""{1}"" ", this.Name, this.Value); } } 

帮手搜索类:

 public class IdentityAttributeSearch { public string Name { get; set; } public object Datum { get; set; } public string RelationshipType { get; set; } } 

用法示例:

  public List FindIdentities(List searchAttributes) { var server = MongoServer.Create("mongodb://localhost/"); var db = server.GetDatabase("IdentityManager"); var collection = db.GetCollection("Identities"); MongoQueryAll qAll = new MongoQueryAll("Relationships"); foreach (var search in searchAttributes) { MongoQueryElement qE = new MongoQueryElement(); qE.QueryPredicates.Add(new MongoQueryPredicate("RelationshipType", search.RelationshipType)); qE.QueryPredicates.Add(new MongoQueryPredicate("Attributes." + search.Name, search.Datum)); qAll.QueryElements.Add(qE); } BsonDocument doc = MongoDB.Bson.Serialization .BsonSerializer.Deserialize(qAll.ToString()); var identities = collection.Find(new QueryComplete(doc)).ToList(); return identities; } 

我相信有一个更好的方法,但现在这个方法很有用,而且似乎足够灵活,可满足我的需求。 欢迎所有建议。

这可能是一个单独的问题,但由于某种原因,对于100,000个文档集,此搜索最多可能需要24秒。 我试过添加各种索引但无济于事; 在这方面的任何指针将是美妙的。