如何在 2 个地图函数中等待并从 mongoDB 检索文档
Posted
技术标签:
【中文标题】如何在 2 个地图函数中等待并从 mongoDB 检索文档【英文标题】:How to await inside 2 map functions and retrieve documents from mongoDB 【发布时间】:2021-05-04 02:56:05 【问题描述】:我需要对返回如下内容的 API 进行一些修改:
[
"_id": "0000000000000000001",
"name": "Random name",
"categories": [
"5eb8548330550e017f8902e6",
"5eb2548630550e117f8909eb",
"5eb6548930550e017f8909e9"
]
,
...,
]
每个结果的类别都作为其各自文档的 ID 返回。 我需要处理结果,以便每个对象的类别字段都有一个对象数组,并且每个对象都有其类别的 ID 和名称。 我举个例子说明结果应该是什么:
[
"_id": "0000000000000000001",
"name": "Random name",
"categories": [
"_id": "5eb8548330550e017f8902e6",
"name": "Category 1",
"_id": "5eb2548630550e117f8909eb",
"name": "Category 2",
"_id": "5eb6548930550e017f8909e9",
"name": "Category 3",
]
,
...,
]
我需要使用普通的 JS 来做到这一点,到目前为止,这就是我所做的,但它返回一个未定义的数组:
const resultArray = await Promise.all(
searchResults.map(async (item) =>
item.categories.map(async (categoryId) =>
return await CategoryType.find( _id: categoryId);
);
)
);
目前我正在尝试获取类别字段中每个 id 的每个类别文档。 我敢打赌,我得到一个未定义数组的原因是我以错误的方式处理异步,但不知道如何处理。
【问题讨论】:
【参考方案1】:严格回答您的问题:您缺少同步(因为Array.prototype.map
'ignores' async):
const resultArray = await Promise.all(
searchResults.map(async (item) =>
const promises = item.categories.map(async (categoryId) =>
// you dont want find, but findOne btw
return await CategoryType.findOne( _id: categoryId);
);
const categories = await Promise.all(promises)
item.categories = categories
return item
)
);
这可以简化为
const resultArray = await Promise.all(
searchResults.map(async item =>
item.categories = await Promise.all(item.categories.map(categoryId =>
return CategoryType.findOne( _id: categoryId)
))
return item
)
);
但正确的做法可能是使用populate
const mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/dummy')
const Category = mongoose.model('Category',
name:String,
, 'categories');
const X = mongoose.model('X',
name:String,
categories: [type: mongoose.Types.ObjectId, ref: 'Category']
, 'xs');
;(async()=>
try
mongoose.set('debug', true)
const xs = await X.find().populate('categories')
console.log('xs : ', xs[0])
finally
mongoose.disconnect()
)()
顺便说一句,你会注意到,猫鼬在后台使用find( _id: $in:[])
,它只发出一个请求(比你做多个findOne
更好)
【讨论】:
完美!非常感谢以上是关于如何在 2 个地图函数中等待并从 mongoDB 检索文档的主要内容,如果未能解决你的问题,请参考以下文章
如何从 2 个集合中读取数据并从两个集合中保存数据并将其保存在 SpringBatch 的第 3 个集合中