数据加载器解析嵌套数组

Posted

技术标签:

【中文标题】数据加载器解析嵌套数组【英文标题】:dataloader resolving nested array 【发布时间】:2019-04-08 11:52:39 【问题描述】:

我有这种形式的架构

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


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

使用 facebook 数据加载器对请求进行批处理

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

【问题讨论】:

你的问题是为什么 Dataloader 会返回 undefined 以获得某些结果? @MikaelLirbank 抱歉,我的问题是将解析格式从这些 ` object, object, object ` 更改为 [[object, object], [object]] 【参考方案1】:

而不是这个加载器函数

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]] 

【讨论】:

以上是关于数据加载器解析嵌套数组的主要内容,如果未能解决你的问题,请参考以下文章

将嵌套数组加载到 bigquery

如何将 numpy 数组列表加载到 pytorch 数据集加载器?

通过参数解析器加载数据时,图像未显示在列表中

4.JVM类加载器深入解析及重要特性剖析

浅谈类加载器与类加载案例解析

从 python 生成 Faker 数据并将其加载到 BigQuery 嵌套表中