我怎么能';和';带C#和MongoDB的多个$elemMatch子句?
我使用的是10Gen认可的mongoDB c#驱动程序,用于c#应用程序和数据浏览,我使用的是Mongovue我怎么能';和';带C#和MongoDB的多个$elemMatch子句?,c#,mongodb,mongodb-.net-driver,C#,Mongodb,Mongodb .net Driver,我使用的是10Gen认可的mongoDB c#驱动程序,用于c#应用程序和数据浏览,我使用的是Mongovue { 'Relationships': { $all: [ {$elemMatch: {'RelationshipType':'Student', 'Attributes.Institution': 'Test1'}}, {$elemMatch: {'RelationshipType':'Staff', 'Attributes.Institution'
{
'Relationships': { $all: [
{$elemMatch: {'RelationshipType':'Student', 'Attributes.Institution': 'Test1'}},
{$elemMatch: {'RelationshipType':'Staff', 'Attributes.Institution': 'Test2'}}
]}
}
以下是两个示例文档架构:
{
"_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#的相同查询:
我通过构造一组类解决了眼前的问题,该类允许生成以下查询:
{ 'Relationships':
{
$all: [
{$elemMatch: {'RelationshipType':'Student', 'Attributes.Institution': 'Test1'}},
{$elemMatch: {'RelationshipType':'Staff', 'Attributes.Institution': 'Test2'}}
]
}
}
以下是类定义:
class MongoQueryAll
{
public string Name { get; set; }
public List<MongoQueryElement> QueryElements { get; set; }
public MongoQueryAll(string name)
{
Name = name;
QueryElements = new List<MongoQueryElement>();
}
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<MongoQueryPredicate> QueryPredicates { get; set; }
public MongoQueryElement()
{
QueryPredicates = new List<MongoQueryPredicate>();
}
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 List<IIdentity> FindIdentities(List<IdentityAttributeSearch> searchAttributes)
{
var server = MongoServer.Create("mongodb://localhost/");
var db = server.GetDatabase("IdentityManager");
var collection = db.GetCollection<MongoIdentity>("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<BsonDocument>(qAll.ToString());
var identities = collection.Find(new QueryComplete(doc)).ToList();
return identities;
}
公共列表FindIdentities(列表搜索属性)
{
var server=MongoServer.Create(“mongodb://localhost/");
var db=server.GetDatabase(“IdentityManager”);
var collection=db.GetCollection(“标识”);
Mongoqueryal qAll=新的Mongoqueryal(“关系”);
foreach(searchAttributes中的var搜索)
{
MongoQueryElement qE=新的MongoQueryElement();
添加(新的MongoQueryPredicate(“RelationshipType”,search.RelationshipType));
添加(新的MongoQueryPredicate(“Attributes.”+search.Name,search.Datum));
qAll.QueryElements.Add(qE);
}
BsonDocument doc=MongoDB.Bson.Serialization
.BsonSerializer.Deserialize(qAll.ToString());
var identies=collection.Find(新QueryComplete(doc)).ToList();
返回身份;
}
我相信有一个更好的方法,但这个方法目前还有效,而且似乎足够灵活,可以满足我的需要。欢迎所有建议
这可能是一个单独的问题,但由于某些原因,对于一个100000个文档集,此搜索可能需要24秒。我曾尝试添加各种索引,但没有效果;这方面的任何指针都会非常棒。一个简单的解决方案是将多个IMongoQuery串在一起,然后用一个查询将它们连接起来。最后:
List<IMongoQuery> build = new List<IMongoQuery>();
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<ObjectToQuery>("nameOfCollectionInMongoDB").FindAs<ObjectToQuery>(_main).ToList();
List build=newlist();
build.Add(Query.ElemMatch(“relations”)、Query.EQ(“RelationshipType”、“Person”));
var searchQuery=String.Format(“/.*{0}.*/”,“sta”);
build.Add(Query.ElemMatch(“Relationships”)、Query.Or(Query.EQ(“Attributes.FirstName”、new-bsonregularpression(searchQuery))、Query.EQ(“Attributes.LastName”、new-bsonregularpression(searchQuery'));
var_main=Query.And(build.ToArray());
var DB=MongoDatabase.Create(“UrlToMongoDB”);
DB.GetCollection(“nameOfCollectionInMongoDB”).FindAs(_main.ToList();
`感谢您的快速回复。不幸的是,您建议的查询没有返回相同的结果。我的文档设计很可能是这里的问题,因为我刚开始使用MongoDB。属性是子文档和属性。机构不是数组。还有什么方法可以将查询字符串直接发送到Find函数吗?@TravisStafford:是的,您可以从字符串生成查询。看看这个我的答案:。我试过了,但没有成功;(.谢谢。这是一个巨大的帮助。阅读你在上一篇评论中指给我的帖子,我能够构建一个快速类来构建我所需的查询字符串。它并不完美,但它可以完成工作。我已经按照要求发布了我的结果。如果能获得一些关于我所采用方法的输入,我会很高兴。
List<IMongoQuery> build = new List<IMongoQuery>();
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<ObjectToQuery>("nameOfCollectionInMongoDB").FindAs<ObjectToQuery>(_main).ToList();