Как вернуть null для элементов, не найденных в агрегации mongodb $ in? - PullRequest
0 голосов
/ 17 февраля 2019

Используя следующую коллекцию примеров:

[
  { _id: ObjectId.createFromHexString("5c51eb681c9d44000091fffa"), name: "name1" },
  { _id: ObjectId.createFromHexString("5c51eb681c9d44000091fffb"), name: "name2" },
  { _id: ObjectId.createFromHexString("5c51eb681c9d44000091fffc"), name: "name3" },
  { _id: ObjectId.createFromHexString("5c51eb681c9d44000091fffe"), name: "name5" }
]

У меня следующий запрос агрегации mongodb:

const keys: ObjectId[] = [
  ObjectId.createFromHexString("5c51eb681c9d44000091fffe"),
  ObjectId.createFromHexString("5c51eb681c9d44000091fffd"),
  ObjectId.createFromHexString("5c51eb681c9d44000091fffc"),
  ObjectId.createFromHexString("5c51eb681c9d44000091fffb"),
];
const aggregation: AggregationCursor<TEntity> = collection.aggregate([
  { $match: { _id: { $in: keys } } },
  { $addFields: { __order: { $indexOfArray: [keys, "$_id"] } } },
  { $sort: { __order: 1 } },
  { $project: { __order: 0 } },
]);

console.log(await aggregation.toArray());

Текущий результат предыдущего запроса агрегации:

[
  { _id: 5c51eb681c9d44000091fffe, name: "name5" },
  { _id: 5c51eb681c9d44000091fffc, name: "name3" },
  { _id: 5c51eb681c9d44000091fffb, name: "name2" }
]

Как видите, длина результата меньше длины искомых элементов.Я хочу получить результат такой же длины искомых элементов, заменив элементы, не найденные на «ноль».

Подводя итог, если это возможно, я хочу получить следующий результат:

[
  { _id: 5c51eb681c9d44000091fffe, name: "name5" },
  null
  { _id: 5c51eb681c9d44000091fffc, name: "name3" },
  { _id: 5c51eb681c9d44000091fffb, name: "name2" },
]

Я делаю вид, что использую это с загрузчиком данных Facebook, где длина результата должна иметь одинаковую длину искомых элементов.В противном случае я получаю следующую ошибку:

TypeError: DataLoader must be constructed with a function which 
accepts Array<key> and returns Promise<Array<value>>, but the function 
did not return a Promise of an Array of the same length as the Array 
of keys.

Вот полный класс, если он может помочь:

import DataLoader from "dataloader";
import { AggregationCursor, Collection, ObjectId } from "mongodb";

export default class BaseLoaders<TEntity> {
    private LoaderId: DataLoader<ObjectId, TEntity>;

    public constructor(collection: Collection<TEntity>) {
        this.LoaderId = new DataLoader((keys) => this.BatchId(collection, keys), {
            cacheKeyFn: (key) => key.toHexString(),
        });
    }

    public get id(): DataLoader<ObjectId, TEntity> {
        return this.LoaderId;
    }

    private async BatchId(collection: Collection<TEntity>, keys: ObjectId[]): Promise<TEntity[]> {
        const aggregation: AggregationCursor<TEntity> = collection.aggregate([
            { $match: { _id: { $in: keys } } },
            { $addFields: { __order: { $indexOfArray: [keys, "$_id"] } } },
            { $sort: { __order: 1 } },
            { $project: { __order: 0 } },
        ]);

        return aggregation.toArray();
    }
}
...