【问题标题】:$PullAll across documents - mongoose$PullAll 跨文档 - 猫鼬
【发布时间】:2020-08-12 11:27:00
【问题描述】:

在我的示例中,我试图找出一种有效的方法来从用户的关注列表中删除 listId 的条目。每个用户集合都有一个监视列表字符串数组,用户可以在其中存储他们正在观看的项目。

示例文档:

 "watchlist": [
    "5ea8449842025217ccff6aec",
    "5ea844eb42025217ccff6aee",
    "5ea8452b42025217ccff6af1"
  ],

为了维护一个干净的数据库,我正在创建一个 azure timer 函数来经常部署以查找和删除不再存在的列表项的监视列表项。可能有许多用户在其监视列表中具有相同的列表 ID 条目。所以我需要定期检查清理它们。

查询:

Post.find({
  $and: [
    { watchlistCleaned: false },
    { auctionEndDateTime: { $lte: Date.now() } }
  ]
}).select("_id").then((res) => {

  for (let i = 0; i < res.length; i++) {

    console.log("res[i]")
    console.log(res[i]._id)


  //pretty sure this would remove the whole watchlist instead of one item so this wouldn't be ideal. 
  //It's needs to pull the items out on a multiple document scale

   // User.deleteMany({ _id: res[i]._id },{watchlist: {$in: res[i]}})

  }

})

期望的输出:

 { _id: 5ea84412048bf54164fe9983 }
 res[i]
 { _id: 5ea8449842025217ccff6aec }
 res[i]
 { _id: 5ea844c042025217ccff6aed }
 res[i]
 { _id: 5ea844eb42025217ccff6aee }
 res[i]
 { _id: 5ea844ed42025217ccff6aef }
 res[i]
 { _id: 5ea844ee42025217ccff6af0 }
 res[i]
 { _id: 5ea8452b42025217ccff6af1 }
 res[i]
 { _id: 5ea85daac6e12a10b09a75a5 }

【问题讨论】:

  • res 有什么作用?它是否有_id 的关注列表项或_id 的用户?还有这是什么watchlistGroup - 你的数组名称是watchlist 还是watchlistGroup
  • 我在上面添加了 res 输出。输出表示尚未为 watchlistCleaned 或设置为 false 的列表,因此它不会两次清理相同的列表。监视列表组是一个错字。我刚才修好了。我在每个用户文档中的数组称为watchlist: [String]
  • 所以res 是需要从用户的watchlist 数组中删除的字符串/ID 列表?
  • 正确。 res _ids 是一些用户文档中的列表 ID,因为他们将该列表添加到他们的监视列表中。这是为了清理旧列表的列表 ID

标签: node.js mongodb mongoose mongodb-query


【解决方案1】:

根据您当前的代码:

 User.deleteMany()
 /** Will actually delete docs from users collection, you need to use .update() or .findAndUpdate() to alter fields inside docs */

如果 res 是列表 ID 的数组,那么您可以这样做:

Post.distinct("_id", { watchlistCleaned: false, auctionEndDateTime: { $lte: Date.now() } }).then((res) => {
  /** So `res` will be an array of unique `_id`'s of Post collection which matches given conditions */
  User.updateMany(
    { watchlist: { $in: res } }, /** get users who have listings ids  */
    {$pullAll : { watchlist : res } } /** pull all listing ids */
  );
});

【讨论】:

  • 我添加了您的解决方案,但它返回了[4/28/2020 7:34:17 PM] (node:19304) UnhandledPromiseRejectionWarning: CastError: Cast to [string] failed for value "[{"$pullAll":["5ea84412048bf54164fe9983","5ea8449842025217ccff6aec","5ea844c042025217ccff6aed","5ea844eb42025217ccff6aee","5ea844ed42025217ccff6aef","5ea844ee42025217ccff6af0","5ea8452b42025217ccff6af1","5ea85daac6e12a10b09a75a5"]}]" at path "watchlist"
  • @user6680 :我错了,有一个错字,更新的答案 - 现在试试..
  • 很棒的解决方案!非常感谢!任何机会你都可以在我发表的另一篇文章中尝试一下,这也与在 document.xml 中操作字符串数组有关。我已经坚持了一个多星期了。我正在使用的 cosmosdb 不支持当前答案:stackoverflow.com/questions/61290693/…
  • @user6680 :我没有工作过 cosmosDB,就我的工作而言,我还使用slice 对数组进行分页,大多数答案都最适合我的想法到目前为止,如果我找到任何东西,会在那里发布一些东西..
猜你喜欢
  • 2014-05-29
  • 2021-02-11
  • 1970-01-01
  • 2015-06-26
  • 2016-10-06
  • 2015-09-06
  • 2015-10-01
  • 1970-01-01
相关资源
最近更新 更多