数据加载器解析嵌套数组

时间:2018-11-05 05:50:05

标签: javascript node.js facebook-graph-api mongoose graphql

我有这种形式的架构

type User{
  id: String!
  name: String
  posts: [Post]
}

type Post {
  id: String!
  userId: String
  body: String
}

使用facebook dataloader批量处理请求

query {
  GetAllUser {
    id
    name
    posts {
      id
      body
    }

这是我已经做过的

    const GetPost = async function (root, params, context, info) {
        const userId = root.id;
        const data = await loader.load(userId);
        //console.log({userId, loader, data});
        return data;
    }

    const loader = new DataLoader(userIds => {
        return PostModel.find({ userId: { $in: userIds } }).then(posts => {
            const postsById = keyBy(posts, "_id");

            console.log({postsById, posts})
            const a = userIds.map(post => postsById[post]);
            //console.log({userIds, posts, postsById, a});
            return a;
        });
    });

如果我使用const postsById = keyBy(posts, "_id");,它将返回[ undefined, undefined, undefined ] as a;如果我返回const postsById = keyBy(posts, "userId");,它将返回

[ { media: [],
       reaction: [],
       comment: [],
       _id: 5bdef792bea4733c64bf5fee,
       body: 'Today is sunday, we give God praise',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-04T13:43:46.253Z,
       updatedAt: 2018-11-04T13:43:46.253Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdd949090d23c5aa430d575,
       body: ' Ooop! going for a holiday soon',
       privacy: 'public',
       userId: 5bdd79ea0fef4004a040d110,
       createdAt: 2018-11-03T12:29:04.385Z,
       updatedAt: 2018-11-03T12:29:04.385Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdd8b5ea95dda4854c50d39,
       body: 'i am a man',
       privacy: 'public',
       userId: 5bdd86dc1c76593b18a727db,
       createdAt: 2018-11-03T11:49:50.244Z,
       updatedAt: 2018-11-03T11:49:50.244Z,
       __v: 0 } ] 

但是console.log({posts})

posts:
   [ { media: [],
       reaction: [],
       comment: [],
       _id: 5bda0d61c255f33550813a86,
       userId: 5bd4dfa30a00291820c7896d,
       body: 'I am very Happy today',
       privacy: 'everyone',
       createdAt: 2018-10-31T20:15:29.717Z,
       updatedAt: 2018-10-31T20:15:29.717Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bda0d74c255f33550813a87,
       userId: 5bd4dfa30a00291820c7896d,
       body: 'Thank God for today',
       privacy: 'everyone',
       createdAt: 2018-10-31T20:15:48.218Z,
       updatedAt: 2018-10-31T20:15:48.218Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bda0d86c255f33550813a88,
       userId: 5bd4dfa30a00291820c7896d,
       body: 'Deeka my bro',
       privacy: 'everyone',
       createdAt: 2018-10-31T20:16:06.042Z,
       updatedAt: 2018-10-31T20:16:06.042Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdc03c4fec5eb3a4cfe2a57,
       body: 'What are you saying',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-02T07:59:00.860Z,
       updatedAt: 2018-11-02T07:59:00.860Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdc03d5fec5eb3a4cfe2a58,
       body: 'What are you saying',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-02T07:59:17.672Z,
       updatedAt: 2018-11-02T07:59:17.672Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdc0493fec5eb3a4cfe2a59,
       body: 'Today is Beautiful',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-02T08:02:27.585Z,
       updatedAt: 2018-11-02T08:02:27.585Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdc0493fec5eb3a4cfe2a5a,
       body: 'Today is Beautiful',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-02T08:02:27.590Z,
       updatedAt: 2018-11-02T08:02:27.590Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdc0493fec5eb3a4cfe2a5b,
       body: 'What do u know about love',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-02T08:02:27.590Z,
       updatedAt: 2018-11-03T03:06:04.308Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdc0493fec5eb3a4cfe2a5c,
       body: 'Love is wicked',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-02T08:02:27.617Z,
       updatedAt: 2018-11-03T03:04:27.168Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdc0ac953b24320885bb19d,
       body: 'Today is really Beautiful',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-02T08:28:57.931Z,
       updatedAt: 2018-11-03T02:48:57.201Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdd8b5ea95dda4854c50d39,
       body: 'i am a man',
       privacy: 'public',
       userId: 5bdd86dc1c76593b18a727db,
       createdAt: 2018-11-03T11:49:50.244Z,
       updatedAt: 2018-11-03T11:49:50.244Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdd8db4702a272b14e5e4d3,
       body: ' Ooop! going for a holiday soon',
       privacy: 'public',
       userId: 5bdd79ea0fef4004a040d110,
       createdAt: 2018-11-03T11:59:48.279Z,
       updatedAt: 2018-11-03T11:59:48.279Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdd949090d23c5aa430d575,
       body: ' Ooop! going for a holiday soon',
       privacy: 'public',
       userId: 5bdd79ea0fef4004a040d110,
       createdAt: 2018-11-03T12:29:04.385Z,
       updatedAt: 2018-11-03T12:29:04.385Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdef776bea4733c64bf5feb,
       body: 'Today is sunday, we give God praise',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-04T13:43:18.777Z,
       updatedAt: 2018-11-04T13:43:18.777Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdef776bea4733c64bf5fec,
       body: 'Today is sunday, we give God praise',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-04T13:43:18.782Z,
       updatedAt: 2018-11-04T13:43:18.782Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdef776bea4733c64bf5fed,
       body: 'Today is sunday, we give God praise',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-04T13:43:18.784Z,
       updatedAt: 2018-11-04T13:43:18.784Z,
       __v: 0 },
     { media: [],
       reaction: [],
       comment: [],
       _id: 5bdef792bea4733c64bf5fee,
       body: 'Today is sunday, we give God praise',
       privacy: 'public',
       userId: 5bd4dfa30a00291820c7896d,
       createdAt: 2018-11-04T13:43:46.253Z,
       updatedAt: 2018-11-04T13:43:46.253Z,
       __v: 0 } ] }

userIds包含此

userIds:
   [ '5bd4dfa30a00291820c7896d',
     '5bdd79ea0fef4004a040d110',
     '5bdd86dc1c76593b18a727db' ],

您可以看到获得了所有帖子,但是要为每个用户返回没有数据加载器的帖子数组,它将使用以下代码工作

const GetPost = async function (root, params, context, info) {
    const post = await PostModel.find({
        userId: root.id
    }).exec();
    if (!post) {
        throw new Error('Post not found');
    }
    console.log({post})
    return post;
}

解析器为posts: GetPost

1 个答案:

答案 0 :(得分:0)

代替此加载器功能

const loader = new DataLoader(userIds => {
    return PostModel.find({ userId: { $in: userIds } }).then(posts => {
      const postsById = keyBy(posts, "_id");
        console.log({postsById, posts})
          const a = userIds.map(post => postsById[post]);
          //console.log({userIds, posts, postsById, a});
          return a;
      });
});

我用了这个

const loader = new DataLoader(userIds => {
    return await PostModel.find({ userId: { $in: userIds } }).then(posts => {
        const allPosts = groupBy(posts, 'userId');
        return userIds.map(post => allPosts[post] || []);
    });
});

使用loadash groupBy首先获得的结果将被格式化为

[[object, object, object], [object, object, object, object], [object]]