Dataloader没有返回相同长度的数组?

时间:2018-03-30 03:48:52

标签: mongodb express mongoose graphql

我正在使用graphql和mongodb(mongoose)构建一个快速JS应用程序。我正在使用facebooks Dataloader批处理和缓存请求。

除了这个用例外,它的工作非常好。

我有一个充满用户帖子的数据库。每个帖子都包含用户ID以供参考。当我打电话返回数据库中的所有帖子时。帖子很好,但如果我试图让每个帖子中的用户。具有多个帖子的用户将仅返回单个用户,因为缓存了第二个用户的密钥。因此来自用户“x”的2个帖子(键)将仅返回1个用户对象“x”。

然而,Dataloader必须返回与其收到的密钥相同数量的承诺。

它有一个选项可以将缓存指定为false,因此每个密钥都会发出请求。但这似乎不适用于我的用例。

很抱歉,如果我没有很好地解释这一点。

这是我的graphql请求

query {
  getAllPosts {
    _id // This is returned fine
    user {
      _id
     }
   }
 }

返回错误:
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.

1 个答案:

答案 0 :(得分:2)

您是否尝试批量发布密钥[1, 2, 3]并希望获得用户结果[{ user1 }, {user2}, { user1 }]

或者您是否尝试批量处理用户密钥[1, 2]并希望获得发布结果[{ post1}, {post3}] and [{ post2 }]

似乎只有在第二种情况下才会遇到键长不同于结果数组长度的情况。

要解决第二个问题,你可以在sql中执行类似的操作:

const loader = new Dataloader(userIDs => {
  const promises = userIDs.map(id => {
    return db('user_posts')
      .where('user_id', id);
  });

  return Promise.all(promises);
})

loader.load(1)
loader.load(2)

所以你返回[[{ post1}, {post3}], [{ post2 }]]哪个dataloader可以解包。

如果你这样做了:

const loader = new Dataloader(userIDs => {
  return db('user_posts')
      .where('user_id', [userIDs]);
})

loader.load(1)
loader.load(2)

您将获得[{ post1}, {post3}, { post2 }],因此会收到错误:the function did not return a Promise of an Array of the same length as the Array of keys

不确定上述内容是否相关/有用。如果您能提供批量加载功能的片段,我可以修改