我有一个像这样的数据集结构:
_id: SomeMongoID,
value: "a",
counter: 1
}
因此,最初我的数据库表为空。
现在我有一个数组,其中值是这样的:
const array = ["a", "a", "a"]
我想要的最初是我第一次进行搜索,因此它将清空结果,因此在这种情况下,插入查询,现在下一次获取条目,只需增加计数器即可。
为此,我编写了代码:
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()通过手动调试进行了检查。任何帮助或建议都非常感谢。
答案 0 :(得分:0)
您不必在这里使用class someTable(tag: Tag) extends Table[(UUID, Array[String], Timestamp)](tag, “Some”) {
def xyzId: Rep[UUID] = column[UUID]("xyz_id")
**def abcId: Rep[Array[String]] = column[Array[String]](“abc_id", O.Length(500))**
def createdTimestamp: Rep[Timestamp] = column[Timestamp]("created_timestamp")
def * : ProvenShape[(UUID,Array[String], Option[UUID],
String, Timestamp)] = (xyzId, abcId, createdTimestamp)
}
}
。您可以只使用map
迭代来等待结果。
for ... of
说明:const testFunction = async(array) => {
try {
for (const x of array) {
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);
不会等待,即使传递函数为map
。而是收集您传递给它的函数的返回值。 async
函数始终返回async
。然后Promise
等待着所有人。但是遍历数据不会等待任何事情。评估第一个Promise.all
关键字的右侧后,它将立即返回promise。但是await
起作用是因为它不使用回调函数。相反,它会评估每个循环并正确等待您要执行的操作。这样执行就非常接近了,好像里面的所有代码都是同步的一样。
答案 1 :(得分:0)
要节省时间并并行加载数据,请先处理我们自己的值。我们创建一个数据结构,该数据结构甚至在单次调用数据库之前就已经计数了相同的值。然后,我们仅在数据库中为数据结构中的唯一键调用数据库。这样可以将示例中的调用次数从3个减少到1个。在我的示例中,我向测试数据添加了两个"b"
值。因此,通话次数将是2而不是5。
然后在数据库中查询唯一键。如果找到条目,则计数器将在测试数组内增加value
次出现的次数。如果未找到,则会创建一个新条目,并将计数器设置为找到的出现次数。
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);