问题描述
我有一个像这样的数据集结构:
I have a Dataset Structure like this:
_id: SomeMongoID,
value: "a",
counter: 1
}
因此,最初我的数据库表为空.现在我有一个数组,其中的值是这样的: const array = ["a","a","a"]
So initially my database table is empty.Now I have an array where value is like:const array = ["a", "a", "a"]
我想要的最初是我第一次搜索,因此它将清空结果,因此在这种情况下,插入查询,现在下一次它得到条目时,只需增加计数器即可.
What I want is initially the first time I do the search, so it will empty result so at that case in insert the query, now next time it get the entry so simply increment the counter.
为此,我编写了代码:
const testFunction = async(array) => {
try {
await Promise.all(
array.map(async x => {
const data = await CollectionName.findOne({value: x}).exec();
// Every time data will return null
if (data) {
//In this case only counter will have to increase
// But this block not run
} else {
//So by this first value will store
const value = new Value({
value: x,
counter: 1
});
await value.save()
}
})
)
} catch (error) {
console.log(error)
}
}
const array = ["a", "a", "a"]
testFunction(array);
问题是它将创建3个条目而不是单个条目.map函数不会等待,我使用console.log()通过手动调试进行了检查.任何帮助或建议都非常感激.
Problem is it will create the 3 entry not single. map function will not wait, I checked through manual debugging using console.log(). Any help or suggestion is really appreciated.
推荐答案
要节省时间并并行加载数据,请先处理我们拥有的值.我们创建了一个数据结构,该数据结构甚至在单次调用数据库之前就已经计数了相同的值.然后,我们仅在数据库中为数据结构中的唯一键调用数据库.这样可以将您的示例中的调用次数从3个减少到1个.在我的示例中,我向测试数据中添加了两个"b"
值.因此通话次数将是2而不是5.
To save time and load data in parallel, first process the values we have ourselves. We create a data structure that has already counted the same values before even making a single call to the database. Then we only call the database for a unique key in our data structure. This reduces the number of calls in your example from 3 to 1. I my example i added two "b"
values to the test data. So the number of calls will be 2 instead of 5.
然后在数据库中查询唯一键.如果找到条目,则将计数器增加测试数组中出现的 value
个值.如果未找到,则会创建一个新条目,并将计数器设置为已发现的出现次数.
The database is then queried for the unique keys. If an entry is found, the counter is increased by the number of value
occurrences inside the test array. If it is not found a new entry is made with the counter set to the number of found occurences.
const testFunction = async (array) => {
try {
// Create a statistics by counting each value fist
// Creates a structure like { a: 3, b: 2}
const countsByValues = array.reduce((acc, value) => {
const newCount = acc[value] ? acc[value] + 1 : 1;
return {
...acc,
value: newCount
};
}, {});
await Promise.all(
// Use object entries to get array of [["a", 3], ["b", 2]]
Object.entries(countsByValues).map(async ([x, count]) => {
const data = await CollectionName.findOne({value: x}).exec();
if (data) {
//In this case only counter will have to increase by the count
data.counter += count;
//save data - insert your code saving code here
await data.save();
} else {
//So by this first value will store
const value = new Value({
value: x,
// new values will be the total count
counter: count
});
await value.save()
}
})
)
} catch (error) {
console.log(error)
}
}
const array = ["a", "a", "b", "b", "a"]
testFunction(array);
这篇关于异步等待在地图功能内无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!