Javascript 函数,用于在将数据保存到MongoDB时返回非空值,但该值无法正常工作
我从API调用中获取一个对象数组,然后根据两个键过滤值:Javascript 函数,用于在将数据保存到MongoDB时返回非空值,但该值无法正常工作,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,我从API调用中获取一个对象数组,然后根据两个键过滤值:story\u title和title。如果两个值都为null,则对象将被过滤。然后,我循环过滤对象数组,将过滤数组中的某些数据保存到mongodb(使用mongoose)。问题是我想用一个title键保存文档,所以我创建了一个函数来检查story\u title或title是否为null并返回非null值 函数工作不正常,因为title中的函数在for循环中返回了一些null值 function pickTitle(title, stor
story\u title
和title
。如果两个值都为null,则对象将被过滤。然后,我循环过滤对象数组,将过滤数组中的某些数据保存到mongodb(使用mongoose)。问题是我想用一个title
键保存文档,所以我创建了一个函数来检查story\u title
或title
是否为null并返回非null值
函数工作不正常,因为title
中的函数在for
循环中返回了一些null
值
function pickTitle(title, story_title) {
if (!story_title) {
return story_title;
} else {
return title
}
}
everyHour: async () => {
try {
data = await axios.get(url);
let posts = data.data.hits;
const filteredPosts = await posts.filter((elem) => {
return (!elem.title || !elem.story_title)
});
for (let filtered of filteredPosts) {
Post.updateOne({
_id: filtered.objectID,
author: filtered.author,
title: await pickTitle(filtered.title, filtered.story_title),
created_at: filtered.created_at,
},
{$setOnInsert: filtered},
{upsert: true},
function(err, numAffected) {
if (err) {
//console.log("err")
} else {
//console.log(numAffected)
}
})
.then(res => {
//console.log(res)
})
.catch(err => {
//console.log(err)
});
}
} catch(error) {
console.log(error);
}
}
这里有几个问题。我将在代码中的一些注释中逐步介绍它们,并在注释代码的正下方提供“解决方案”
- 您正在等待非异步的呼叫。。。不要那样做。Array.filter不是异步操作
- 您的函数
正在picktile
ed中,但它不是异步的wait
- 你的解决承诺在一个循环中,这通常被认为是不好的做法。将承诺添加到数组中,并使用
Promise.all()解析每个人
- 最后,您的“过滤”逻辑过滤空
或标题
。这意味着只有一个需要保持真实。但也有可能两者都是空的。因此,故事标题
函数在两者恰好为空时返回空值。如果希望至少其中一个包含值,则需要更改array.filter的工作方式picktile
const picktile=(标题,故事标题)=>{
如果(!故事标题){
返回故事标题;
}
返回标题;
};
异步()=>{
试一试{
数据=等待axios.get(url);
const posts=data.data.hits;
//const filteredPosts=wait posts.filter(elem=>(!elem.title | | |!elem.story_title)){
//如果(错误){
////console.log(“err”)
//}其他{
////console.log(numAffected)
// }
// })
//。然后(res=>{
////console.log(res)
// })
//.catch(错误=>{
////console.log(错误)
// });
推(
Post.updateOne({
_id:filtered.objectID,
作者:filtered.author,
//标题:等待pickTitle(filtered.title,filtered.story_title),//{
如果(错误){
//console.log(“err”)
}否则{
//console.log(numAffected)
}
})
);
}
返回承诺。全部(假设更新);
}捕获(错误){
console.log(错误);
}
};
谢谢您的帮助!但它不起作用。首先,在某些情况下,我仍然将title
保存为null。第二,我在末尾得到了这个错误(节点:3240)unhandledPromisejectionWarning:unhandledPromiseRejection(拒绝id:1):MongoError:E11000重复密钥错误集合:5b913e0096e8216a560bcbe3\u testing.posts索引:\u id\uDup密钥:{:“17904322”}
我认为我没有正确解释自己。我需要做的一件事是,仅当对象不在API中时才保存该对象。在尝试删除和重写所有内容后,关于pickTitle中的异步调用的问题是一个错误,很抱歉,这是因为您总是根据筛选条件进行插入。尝试将筛选内容简化为对象id:Post.updateOne({u id:filtered.objectID},…)
您正试图筛选要更新到的确切字段,因此筛选器从不匹配,它将此视为插入并抛出该重复键。
const pickTitle = (title, story_title) => {
if (!story_title) {
return story_title;
}
return title;
};
async () => {
try {
data = await axios.get(url);
const posts = data.data.hits;
// const filteredPosts = await posts.filter(elem => (!elem.title || !elem.story_title)); <-- you are awaiting on a filter... don't do that
const filteredPosts = posts.filter(elem => (!elem.title || !elem.story_title));
const filteredPostAnotherWay = posts.filter(post => { // <-- This might be more of what you want...
let allowed = false;
if (!post.title) {
allowed = true;
}
if (!post.story_title) {
allowed = true;
}
return allowed;
});
const postUpdates = [];
for (const filtered of filteredPosts) {
// Post.updateOne({ <-- You are resolving promises inside a for loop. While it may work, it's generally not advised to do this. Resolve everything with promise.all instead....
// _id: filtered.objectID,
// author: filtered.author,
// title: await pickTitle(filtered.title, filtered.story_title),
// created_at: filtered.created_at,
// story_url: filtered.story_url
// },
// { $setOnInsert: filtered },
// { upsert: true },
// (err, numAffected) => {
// if (err) {
// // console.log("err")
// } else {
// // console.log(numAffected)
// }
// })
// .then(res => {
// // console.log(res)
// })
// .catch(err => {
// // console.log(err)
// });
postUpdates.push(
Post.updateOne({
_id: filtered.objectID,
author: filtered.author,
// title: await pickTitle(filtered.title, filtered.story_title), // <-- You are awaiting a non asynchronous function... why?
title: pickTitle(filtered.title, filtered.story_title),
created_at: filtered.created_at,
story_url: filtered.story_url
},
{ $setOnInsert: filtered },
{ upsert: true },
(err, numAffected) => {
if (err) {
// console.log("err")
} else {
// console.log(numAffected)
}
})
);
}
return Promise.all(postUpdates);
} catch (error) {
console.log(error);
}
};