Я решил непосредственную проблему путем создания набора классов, который позволял генерировать следующий запрос:
{ '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 class IdentityAttributeSearch
{
public string Name { get; set; }
public object Datum { get; set; }
public string RelationshipType { get; set; }
}
Пример использования:
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;
}
Я уверен, что есть намного лучший способ, но пока он работает и, кажется, достаточно гибок для моих нужд. Все предложения приветствуются.
Вероятно, это отдельный вопрос, но по какой-то причине этот поиск может занять до 24 секунд для набора документов из 100 000. Я пытался добавить различные индексы, но безрезультатно; любые указатели в этом отношении были бы невероятны.