javascript中的嵌套MongoDB查询
Posted
技术标签:
【中文标题】javascript中的嵌套MongoDB查询【英文标题】:Nested MongoDB query in javascript 【发布时间】:2019-11-11 16:36:36 【问题描述】:这是一个 GraphQL 解析器。 问题在于使用 async/await 处理承诺。
我尝试过实现promise处理,但我无法正确设置它,我对promise处理没有太多经验,一些学习资料会很有帮助。
我的理解是脚本将在调用 await 的地方停止,并在 await 调用完成后继续。但它绕过了等待。 返回值后等待调用结束
allDocs: async (args, context) => context().then(async client =>
let db = client.db(dbName)
const id = args.identifier.trim()
let nameArr = []
return await db.collection("collection").find(
$or: [
"a.iden": id
,
"b.iden": id
]
).toArray().then(async (arr) =>
let year
arr.map(async element =>
let pmcid = element.pmc_id.toUpperCase()
try
year = await db.collection("Another_collection").findOne("pmcid" : query)["year"]
catch (e)
year = null
element["publication_year"] = year
)
return await arr
).then((arr)=>
client.close()
return
"documents": arr,
"count": arr.length,
"searchkey": id
)
),
预期的返回值应该有“publication_year”作为某个年份,它现在给出null。
感谢您的帮助
【问题讨论】:
【参考方案1】:您似乎将 Promises 与 async/await 混合在一起,这有点难以理解。通过更改 Promise 位以使用 async/await 来分解代码总是更好,因为这将帮助您缩小问题范围。您也可以将整个块包装在 try/catch 中,这样可以相对轻松地处理同步和异步错误。
因此,首先,您可以更改上下文函数调用,该函数调用返回一个使用 async await as 的承诺
allDocs: async (args, context) =>
try
const client = await context()
....
catch(err)
然后对 toArray()
函数调用执行相同的操作,该函数调用返回一个可以通过 async/await 解决的承诺:
allDocs: async (args, context) =>
try
const client = await context()
const db = client.db(dbName)
const id = args.identifier.trim()
const results = await db.collection('collection').find(
'$or': [
'a.iden': id ,
'b.iden': id
]
).toArray()
const arr = results.map(async doc =>
const pmcid = doc.pmc_id.toUpperCase()
const year = await db.collection('Another_collection')
.findOne('pmcid' : pmcid )
return
...doc,
publication_year: year
)
client.close()
return
'documents': arr,
'count': arr.length,
'searchkey': id
catch(err)
// handle error
可以使用$lookup
管道在单个调用中而不是在映射循环中调用另一个集合以获取publication_year
。考虑以下管道
allDocs: async (args, context) =>
try
const client = await context()
const db = client.db(dbName)
const id = args.identifier.trim()
const pipeline = [
'$match':
'$or': [
'a.iden': id ,
'b.iden': id
]
,
'$lookup':
'from': 'Another_collection',
'let': 'pmcId': '$pmc_id' ,
'pipeline': [
'$match':
'$expr':
'$eq': [
'$pmcid',
'$toUpper': '$$pmcId'
]
],
'as': 'pmc'
,
'$addFields':
'publication_year':
'$arrayElemAt': [ '$pmc.year', 0 ]
,
'$project': 'pmc': 0
]
const arr = await db.collection('collection').aggregate(pipeline).toArray()
client.close()
return
'documents': arr,
'count': arr.length,
'searchkey': id
catch(err)
// handle error
【讨论】:
谢谢,很高兴知道聚合方法,它让事情变得简单并开辟了新的维度。以上是关于javascript中的嵌套MongoDB查询的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 findOne 查询 mongodb 并排除数组中的一些嵌套字段