Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.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
Javascript 猫鼬:确保数组永远不会超过一定数量的项目_Javascript_Mongodb_Mongoose - Fatal编程技术网

Javascript 猫鼬:确保数组永远不会超过一定数量的项目

Javascript 猫鼬:确保数组永远不会超过一定数量的项目,javascript,mongodb,mongoose,Javascript,Mongodb,Mongoose,试图找出Mongoose中set操作的确切语法。我有一个如下所示的模式: const userSchema = mongoose.Schema({ instagram: { images: [{ id: { type: String }, media_type: { type: String }, media_url: { type: String }, timestamp: { type: Date } }] } });

试图找出Mongoose中
set
操作的确切语法。我有一个如下所示的模式:

const userSchema = mongoose.Schema({
  instagram: {
    images: [{
      id: { type: String },
      media_type: { type: String },
      media_url: { type: String },
      timestamp: { type: Date }
    }]
  }
});

const T = async () => {
  try {
     //The result document won't be found, if array_field have more then 30 elements.
     let result = User.findOneAndUpdate({$expr: {$lte: [{$size: "$array_field"}, 30]}});
     if (!result) {
        //No such documents
     } else {
       //you could add as much elements as you want via for loop for example
       result.array_field.addToSet(element)
       //also you could check your array_field.length after it, before saving
       await result.save()
     }
  } catch (e) {
    console.error(e)
  }
}
我会定期用用户最新的Instagram照片更新此阵列,如下所示:

User.findOneAndUpdate({u id},{$addToSet:{“instagram.images”:{$each:arr}})


如何确保阵列更新为最新的图像,但永远不会超过30个图像?功能应该是,如果阵列有20个图像,并且有11个新图像要添加,则所有11个新图像都应添加到阵列中,并且应删除阵列中当前存在的最后一项。

如果我正确理解您的逻辑,请尝试运算符,如下所示:

const userSchema = mongoose.Schema({
  instagram: {
    images: [{
      id: { type: String },
      media_type: { type: String },
      media_url: { type: String },
      timestamp: { type: Date }
    }]
  }
});

const T = async () => {
  try {
     //The result document won't be found, if array_field have more then 30 elements.
     let result = User.findOneAndUpdate({$expr: {$lte: [{$size: "$array_field"}, 30]}});
     if (!result) {
        //No such documents
     } else {
       //you could add as much elements as you want via for loop for example
       result.array_field.addToSet(element)
       //also you could check your array_field.length after it, before saving
       await result.save()
     }
  } catch (e) {
    console.error(e)
  }
}
因此,如果
array\u字段
少于30个元素,则会找到它,并更新它。您还可以将
$size
与:
$gte
/
$lte


$addToSet
保证使用唯一值更新数组。因此,在保存到集合之前,您可以再次检查它(如果您愿意)。

使用
$addToSet
操作符无法实现这一点。您有两种选择:

  • 确保您只获取唯一的图像,然后您可以使用
    $push
    结合操作员来实现这一点
  • 如果无法确保图像的唯一性,则必须先获取用户并在代码中筛选数组,然后再继续更新:
  • 最后,将选项1中的语法与
    fileterdImages
    一起使用:

    User.findOneAndUpdate({ _id }, 
        { $push: { "instagram.images": { $each: fileterdImages, $slice: -30 } } });
    

    请注意,mongoose倾向于为嵌套对象自动生成一个
    \u id
    字段,使得
    $addToSet
    一开始就不那么相关。

    这都是假设图像是按时间顺序推送的。否则,您每次都必须执行代码中的所有逻辑。谢谢您的详细回答!我会同意你的第一个解决方案。仅供参考,我的嵌套obj中也有
    \u id:false
    ,但为了简单起见,我没有将其包含在内,尽管我可能必须清楚。如果其中一个答案有帮助,请您将问题标记为已解决或至少对其进行投票?