如何在Mongoose中使用DataLoader

时间:2019-09-16 23:47:54

标签: javascript mongodb mongoose graphql dataloader

我正在尝试与Mongoose一起构建以下DataLoader用例:

export const PurchaseOrderType = new GraphQLObjectType({
    name: "PurchaseOrder",
    description: "PurchaseOrder",
    interfaces: () => [NodeInterface],
    isTypeOf: value => value instanceof PurchaseOrderModel,
    fields: () => ({
        id: {
            type: new GraphQLNonNull(GraphQLID),
            resolve: obj => dbIdToNodeId(obj._id, "PurchaseOrder")
        },
        name: {
            type: new GraphQLNonNull(GraphQLString)
        },
        customer: {
            type: CustomerType,
            resolve: (source, args, context) => {
                return context.customerLoader.load(source.customer_id);
            }
        }
    })
});

export default () => {
    return graphqlHTTP((req, res, graphQLParams) => {
        return {
            schema: schema,
            graphiql: true,
            pretty: true,
            context: {
                customerLoader: customerGetByIdsLoader()
            },
            formatError: error => ({
                message: error.message,
                locations: error.locations,
                stack: error.stack,
                path: error.path
            })
        };
    });
};



export const customerGetByIdsLoader = () =>
    new DataLoader(ids => {
        return customerGetByIds(ids);
    });


export const customerGetByIds = async ids => {
    let result = await Customer.find({ _id: { $in: ids }, deletedAt: null }).exec();

    let rows = ids.map(id => {
        let found = result.find(item => {
            return item.id.equals(id);
        });

        return found ? found : null; << === found always undefined
    });

    return rows;
};

加载多个PurchaseOrders时遇到以下问题:

  1. 在DataLoader的ids参数中多次调用一个customer_id。因此,在连续的调用中,对我的加载程序的多个请求都被调用示例5cee853eae92f6021f297f45。这表明缓存无法正常工作。

  2. 即使比较正确的ID,我在处理读取结果时发现的变量也始终设置为false。

1 个答案:

答案 0 :(得分:0)

您可以使用findOne

export const customerGetByIds = async ids => {
   let result = await Customer.find({ _id: { $in: ids }, deletedAt: null }).exec();
   const rows = []
   let promiseAll = ids.map(async (id) => {
      let found = result.filter(item => item.id.toString() === id.toSring());
      if(found) {
         rows.push(found[0])
         return found[0] 
      }
      return null; 
   });
   await Promise.all(promiseAll);
   return rows;
};