【问题标题】:How to use DataLoader with Mongoose如何将 DataLoader 与 Mongoose 一起使用
【发布时间】:2020-01-17 19:26:32
【问题描述】:

我正在尝试与 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;
};

我在加载多个 PurchaseOrder 时遇到以下问题:

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

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

【问题讨论】:

    标签: javascript mongodb mongoose graphql dataloader


    【解决方案1】:

    你可以使用 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;
    };
    

    【讨论】:

    • 这不是一个可接受的答案,因为findOne 会导致多次数据库调用,从而成倍增加数据的加载时间。
    • 好的。上述解决方案对您不起作用吗?
    • 甚至没有测试,因为正如我所说,这会增加不允许的延迟。所以,简而言之,这并不能解决我的问题。
    猜你喜欢
    • 2019-03-17
    • 2019-12-08
    • 2021-01-02
    • 2022-12-04
    • 2023-03-16
    • 1970-01-01
    • 2019-04-15
    • 2015-12-03
    • 1970-01-01
    相关资源
    最近更新 更多