我想在我的应用程序中实现转发功能。我使用Mongoose并具有UserMessage模型,并且将转发存储为{userId, createdAt}类型的对象数组,其中createdAt是发生转发的时间。消息模型具有其自己的createdAt字段。

我需要创建基于createdAt字段合并在一起的原始消息和转推消息的提要。无论是在单个查询中还是在单独的查询中进行合并,然后在JavaScript中进行合并,我都无法进行合并。我可以在Mongoose中完成一个查询吗?如果没有找到最后一条消息的合并插入点和索引?

到目前为止,我只获取原始消息。

我的Message模型:

const messageSchema = new mongoose.Schema(
  {
    fileId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'File',
      required: true,
    },
    userId: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'User',
      required: true,
    },
    likesIds: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
    reposts: [
      {
        reposterId: {
          type: mongoose.Schema.Types.ObjectId,
          ref: 'User',
        },
        createdAt: { type: Date, default: Date.now },
      },
    ],
  },
  {
    timestamps: true,
  },
);


编辑:现在我有,但分页符被打破。我试图将newCreatedAt字段用于光标,这似乎不起作用。从前端传递newCreatedAt时,它将在第二次调用中返回空数组。

  messages: async (
      parent,
      { cursor, limit = 100, username },
      { models },
    ) => {
      const user = username
        ? await models.User.findOne({
            username,
          })
        : null;

      const options = {
        ...(cursor && {
          newCreatedAt: {
            $lt: new Date(fromCursorHash(cursor)),
          },
        }),
        ...(username && {
          userId: mongoose.Types.ObjectId(user.id),
        }),
      };

      console.log(options);

      const aMessages = await models.Message.aggregate([
        {
          $addFields: {
            newReposts: {
              $concatArrays: [
                [{ createdAt: '$createdAt', original: true }],
                '$reposts',
              ],
            },
          },
        },
        {
          $unwind: '$newReposts',
        },
        {
          $addFields: {
            newCreatedAt: '$newReposts.createdAt',
            original: '$newReposts.original',
          },
        },
        { $match: options },
        {
          $sort: {
            newCreatedAt: -1,
          },
        },
        {
          $limit: limit + 1,
        },
      ]);

      const messages = aMessages.map(m => {
        m.id = m._id.toString();
        return m;
      });
      //console.log(messages);

      const hasNextPage = messages.length > limit;
      const edges = hasNextPage ? messages.slice(0, -1) : messages;

      return {
        edges,
        pageInfo: {
          hasNextPage,
          endCursor: toCursorHash(
            edges[edges.length - 1].newCreatedAt.toString(),
          ),
        },
      };
    },


这是查询。工作之一:

Mongoose: messages.aggregate([{
    '$match': {
        createdAt: {
            '$lt': 2020 - 02 - 02 T19: 48: 54.000 Z
        }
    }
}, {
    '$sort': {
        createdAt: -1
    }
}, {
    '$limit': 3
}], {})


和不工作的一个:

Mongoose: messages.aggregate([{
    '$match': {
        newCreatedAt: {
            '$lt': 2020 - 02 - 02 T19: 51: 39.000 Z
        }
    }
}, {
    '$addFields': {
        newReposts: {
            '$concatArrays': [
                [{
                    createdAt: '$createdAt',
                    original: true
                }], '$reposts'
            ]
        }
    }
}, {
    '$unwind': '$newReposts'
}, {
    '$addFields': {
        newCreatedAt: '$newReposts.createdAt',
        original: '$newReposts.original'
    }
}, {
    '$sort': {
        newCreatedAt: -1
    }
}, {
    '$limit': 3
}], {})

最佳答案

可以在一个查询中完成,尽管有点hacking:

db.collection.aggregate([
    {
        $addFields: {
            reposts: {
                $concatArrays: [[{createdAt: "$createdAt", original: true}],"$reports"]
            }
        }
    },
    {
        $unwind: "$reposts"
    },
    {
        $addFields: {
            createdAt: "$reposts.createdAt",
            original: "$reposts.original"
        }
    },
    {
        $sort: {
            createdAt: -1
        }
    }
]);


您可以使用original字段向查询添加任何其他逻辑,带有original: true的文档是原始帖子,而其他文档则是转推。

关于javascript - 在MongoDB中通过转发实现feed,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60025851/

10-10 03:16