Может ли этот оптимизированный конвейер агрегации $ lookup быть дополнительно оптимизирован? - PullRequest
0 голосов
/ 04 июня 2019

У меня есть две коллекции сущностей 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; }
}
...