Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 如何在查找聚合后按id查找_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

Mongodb 如何在查找聚合后按id查找

Mongodb 如何在查找聚合后按id查找,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我在mongodb中有一个新闻文章集合,另一个集合将用户ID映射到文章ID,并具有“like”状态,如果用户和文章不存在条目,则状态可以是“like”或“loke”或“none” 以下是两种模式: // news collection const articleSchema = new Schema({ title: String, content: String, }) // newslikes collection const articleLikeSchema = new Sch

我在mongodb中有一个新闻文章集合,另一个集合将用户ID映射到文章ID,并具有“like”状态,如果用户和文章不存在条目,则状态可以是“like”或“loke”或“none”

以下是两种模式:

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

您可以在mongodb3.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"] }
  }}
])
或者你尝试的方式

基本上,这里您需要为字段
userLikeStatus
设置,也就是说,如果数组后面的值为1,那么用户喜欢它,否则不喜欢

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": {
      "$let": {
        "vars": {
          "array": {
            "$filter": {
              "input": "$likes",
              "as": "like",
              "cond": { "$eq": ["$$like.user", mongoose.Types.ObjectId("5ccf13adcec5e6d84f940417")] }
            }
          }
        },
        "in": {
          "$ifNull": [{ "$arrayElemAt": ["$$array.state", 0] }, "none"]
        }
      }
    }
  }}
])

我不明白为什么它里面有一个
$cond
,然后是一个
$gt
和一个
$filter
,所以第一种方法有一个错误:
$in需要一个数组作为第二个参数,发现:objectId
这不是我真正想要的。我想要一个like状态字符串,如果行不存在,它可以是“like”或“loke”或“none”。我不想要一个简单的布尔值,大多数时候我都不测试。我刚刚记住的大部分语法。我已经测试了昨天发布的代码,但是现在我很忙,无法测试它。给我最后一次机会。如果你已经发布了真实的数据和样本输出,那么直到我正确回答你为止。