DataLoader在知道密钥之前获取文档

时间:2017-10-17 12:50:14

标签: javascript node.js graphql graphql-js

我使用以下架构在MongoDB中保存了大约3350个文档:

const item = new Schema({
    id: {
        type: Number,
        required: true,
        index: true
    },
    name: {
        type: String,
        required: true,
        index: true
    },
    store: {
        type: Number,
        required: true
    },
    rsbuddy: {
        type: [rsbuddy],
        default: []
    }
})

rsbuddy中的item字段通常存储了大约30,000到40,000个条目,因此我只想在请求这些文档时获取这些文档。此外,我的根GraphQL查询如下所示(它是用Apollo构建的):

const RuneScapeQuery = `
    type RuneScapeQuery {
        items: [Item]
        item(id: Int): Item
        updates: [Update]
    }
`

基本上,我想要发生的是当我正在批处items查询的请求时,我希望它默认查询所有文档。我目前有以下代码来执行此操作:

resolvers: {
  RuneScapeQuery: {
    items: async (root, args, { loaders }) =>
      fetchItems()
        .then(items => items.map(item => item.id))
        .then(ids => loaders.itemLoader.loadMany(ids)),
    item: (root, { id }, { loaders }) => loaders.itemLoader.load(id)
  }
}

然而,这种方法的问题在于,MongoDB的第一次往返是花费所有项目的ID。其次,dataloader将为每个个人项目请求所有数据,而不是使用find函数来检索许多文档。

const fetchItem = id =>
    Item.findOne({ id }, { rsbuddy: false })

const itemLoader = new DataLoader(keys => {
    return Promise.all(keys.map(fetchItem))
})

改善这种结构并简化它的好方法是什么?

修改

为了澄清我的问题,我将尝试解决主要问题的问题,那就是时间。如果您将DataLoader添加到等式中,则会从缓存中提供项目。但是,由于始终需要首先获取实时密钥的性质,查询将保持需要11秒。第一次,它将花费大约30秒,因为它需要获取密钥然后逐个获取项目。但是,之后再次需要11秒,因为需要首先获取密钥。

0 个答案:

没有答案