У меня есть две коллекции сущностей Author
и Book
.Они находятся в отношении «один ко многим» через коллекцию соединений под названием JoinAuthorBook
, которая имеет два поля ParentID
и ChildID
.ParentID хранит идентификатор автора, а ChildID имеет идентификатор книги.
у меня есть функция, которая принимает IAggregateFluent [Book] и возвращает IAggregateFluent [Author], выполнив два этапа поиска $, и следующеерезультирующий конвейер агрегации, который отправляется на mongodb.
Мой вопрос: знаете ли вы более эффективный способ достижения того же конечного результата при том же входе?в частности, является ли $ replaceRoot с позицией $ arrayElemAt 0 лучшим способом для этого?
Я также разместил код c #, который генерировал свободный запрос.поэтому я был бы признателен, если бы вы могли предлагать решения с использованием строго типизированного кода C #, так как я буду работать с ограничениями драйвера c #, и моя база кода не может иметь никаких волшебных строк.
ура!
{
"$match": {
"_id": ObjectId("5cf68e18a8e892318888a63f")
}
}, {
"$lookup": {
"from": "JoinAuthorBook",
"localField": "_id",
"foreignField": "ChildID",
"as": "Results"
}
}, {
"$replaceRoot": {
"newRoot": {
"$arrayElemAt": ["$Results", NumberInt("0")]
}
}
}, {
"$lookup": {
"from": "Authors",
"localField": "ParentID",
"foreignField": "_id",
"as": "Results"
}
}, {
"$replaceRoot": {
"newRoot": {
"$arrayElemAt": ["$Results", NumberInt("0")]
}
}
}
код драйвера c #:
public IAggregateFluent<TParent> GetParents<TParent, TChild>(IAggregateFluent<TChild> children)
{
return children
.Lookup<TChild, JoinRecord, Joined<JoinRecord>>(
JoinCollection,
c => c.ID,
r => r.ChildID,
j => j.Results)
.ReplaceRoot(j => j.Results[0])
.Lookup<JoinRecord, TParent, Joined<TParent>>(
AuthorCollection,
r => r.ParentID,
p => p.ID,
j => j.Results)
.ReplaceRoot(j => j.Results[0]);
}
public class Joined<T> : JoinRecord
{
public T[] Results { get; set; }
}
public class JoinRecord : Entity
{
public string ParentID { get; set; }
public string ChildID { get; set; }
}