查找聚合后如何按ID查找

时间:2019-05-05 17:04:07

标签: mongodb mongodb-query aggregation-framework

我在mongodb中有一组新闻文章,另一个是将用户ID映射到文章ID并具有“喜欢”状态的集合,如果没有条目,状态可以为“喜欢”或“不喜欢”或“无”与用户和文章存在。

这是两个模式:

// news collection
const articleSchema = new Schema({
  title: String,
  content: String,
})

// newslikes collection
const articleLikeSchema = new Schema({
  user: { type: Schema.Types.ObjectId, ref: 'Client' },
  article: { type: Schema.Types.ObjectId, ref: 'News' },
  state: { type: String, enum: ['like', 'dislike'] }
})

我正在尝试编写一个聚合查询,该查询使用$lookup将这两个集合连接在一起,然后在所有文章中查找特定用户的状态。这是我到目前为止的内容:

  const results = await News.aggregate([
    { $match: query },
    { $sort: { date: -1 } },
    { $skip: page * pageLength },
    { $limit: pageLength },
    { $lookup: {
      from: 'newslikes',
      localField: '_id',
      foreignField: 'article',
      as: 'likes'
    } },
    { $project: {
      title: 1,
      likes: 1,
      content: 1,
      // numLikes: { $size: '$likes' }
      userLikeStatus: {
        $filter: {
          input: '$likes',
          as: 'like',
          cond: {
            $eq: ['$user._id', '5ccf13adcec5e6d84f940417']
          }
        }
      }
    } }
  ])

但是这不起作用。我在做什么甚至是正确的方法,还是有比$filter更好的方法呢?

1 个答案:

答案 0 :(得分:1)

您可以在mongodb 3.6 及更高版本

中使用以下聚合
News.aggregate([
  { "$match": query },
  { "$sort": { "date": -1 } },
  { "$skip": page * pageLength },
  { "$limit": pageLength },
  { "$lookup": {
    "from": "newslikes",
    "let": { "articleId": "$_id" },
    "pipeline": [
      { "$match": {
        "$expr": { "$eq": [ "$article", "$$articleId" ] },
        "user": mongoose.Types.ObjectId("5ccf13adcec5e6d84f940417")
      }}
    ],
    "as": "likes"
  }},
  { "$addFields": {
    "userLikeStatus": { "$ifNull": [{ "$arrayElemAt": ["$likes.state", 0] }, "none"] }
  }}
])

或者您尝试的方式

基本上,您需要在字段{{1}中放置$cond,即如果$size之后的数组的$filter$gte 1,则用户喜欢它否则没有。

userLikeStatus