【发布时间】:2017-08-08 03:57:58
【问题描述】:
我的软件出现错误,导致 mongodb 中的引用损坏。 示例网站文档:
{
"_id" : ObjectId("58d55766f12ba71c4131468a"),
"name" : "abc",
"annotations" : [
ObjectId("58d5580b507af01cc77c5155"),
ObjectId("58d55888b83e461d768fc0eb"),
ObjectId("58d8d0b434f0b621272869be"),
ObjectId("58d8d0f034f0b621272869bf")
]
数组中的某些 ObjectId 不再存在。 我正在尝试找到一种方法来删除对注释对象的损坏引用。 这就是我想要做的:
const mongoose = require('mongoose');
const config = require('config');
const Promise = require('bluebird');
mongoose.Promise = Promise;
mongoose.connect(config.get("DBUrl"), {useMongoClient: true});
require('./model/Website');
require('./model/Annotation');
const Website = mongoose.model('Website');
const Annotation = mongoose.model('Annotation');
Website.find({})
.then(function (websites) {
for (let website of websites) {
let queue = [];
for (let annotationId of website.annotations) {
queue.push(Annotation.find({_id: annotationId}, {_id: 1})
.then(function (ann) {
if (!ann) {
website.pull(annotationId);
}
return Promise.resolve(website);
})
);
}
Promise.all(queue)
.then(function (ws) {
console.log('updated website ' + website.name)
return website.save();
})
.catch(function (err) {
throw new Error(err);
});
}
});
我无法让 Promise.all 正常工作。它在查找函数的 .then 之前执行。 请帮我找出错误。
使用普通的 mongodb 是否有更优雅的方法来做到这一点?
谢谢
【问题讨论】:
-
我会跳过第二个 for 循环(website.annotations 的annotationId),而是进行
Annotation.find({_id: {$in: website.annotations}})之类的查询,然后将查询结果与原始列表进行比较。如果您不担心竞争条件,您可以将 website.annotations 设置为结果数组。如果需要,也许可以查看 lodash 以轻松找到两个数组之间的区别(确保在比较它们之前使用 .toString() objectIds)我也会考虑在这里使用 async 或流而不是 promise.all (尤其是当网站数量可以大)
标签: javascript node.js mongodb mongoose bluebird