在 Mongodb 中使用 $function 获取请求

Posted

技术标签:

【中文标题】在 Mongodb 中使用 $function 获取请求【英文标题】:GET request with $function in Mongodb 【发布时间】:2021-10-29 14:08:54 【问题描述】:

总结: 我正在尝试将 Mongodb 聚合的结果与第三方 API 相结合,但找不到任何相关内容。

解释: 下面的Express 路由查找在提供的日期之后发生且未被取消的所有游戏。下一步是从第三方 API 获取该单个游戏的一些数据并将其附加到对象并继续在管道中继续进行

问题: 似乎你不能在$function 内有XHR 请求(我在官方文档中没有找到任何内容,所以我不确定)

        const today = moment();
        today.year(2021);
        today.month(5);
        let response = await Game.aggregate([
            
                $match: 
                    $expr: 
                        $and: [
                             $gte: ["$date", moment(today).startOf('day').toDate()] ,
                             $eq: ["$canceled", false] ,
                        ]
                    
    
                
            ,
             $sort:  date: 1  ,
            
                $addFields: 
                    boxScore: 
                        $function:
                        
                            body: async function (season, week, home_team) 
                                const result = await axios.get(
                                    `SINGLEGAMEURL/$season/$week/$home_team`,
                                    
                                        headers: 
                                            'Subscription-Key': 'SOMEKEY',
                                        ,
                                    
                                );
                                return result.data;
                            ,
                            args: ["$season", '$week', 'home_team'],
                            lang: "js"
                        
                    
                
            
        ]);

非常感谢您对此的任何帮助/指导,干杯!

【问题讨论】:

您是否遇到任何错误? javascript 函数在数据库服务器上运行。因此,作为服务器一部分的 JS 引擎需要具有您在 $function 中调用的外部函数。您在$function 中进行的调用正在使用一些不属于普通 JS 的软件组件,我明白了。 不,我没有收到任何错误,boxScore 字段返回一个空对象。如果我删除async,我会收到一条错误消息Mongodb Error: axios is not defined 当服务器调用“body”时,它会同步调用,甚至会在尝试执行等待的函数调用之前返回一个promise。 我认为现在已经得到了这么多,所以问题是:有没有办法解决这个问题? 为什么在得到汇总结果后不调用?你可以在结果上用 javascript 做到这一点。据我所知,我只允许 function() 作为正文,我认为没有使用库的方法,你需要我认为只是 JS 代码。 【参考方案1】:

我怀疑您是否可以在 $function 中使用异步函数,因为它们返回解析为 result.data 的承诺,而不是数据本身。相反,请考虑在快速中间件中执行异步操作, MongoDB 操作之后。像这样的:

app.use("/path", async function(req, res) 
  const today = moment();
  today.year(2021);
  today.month(5);
  let response = await Game.aggregate([
    $match: ...,
    $sort: date: 1
  ]).toArray();
  await Promise.all(response.map(row => axios.get(
    `SINGLEGAMEURL/$row.season/$row.week/$row.home_team`,
    headers: 'Subscription-Key': 'SOMEKEY'
  ).then(function(result) 
    row.boxScore = result.data;
  )));
  res.json(response);
);

(可能Promise.all 可以避免,但我对 async/await 的经验不足,不知道如何操作。)

【讨论】:

以上是关于在 Mongodb 中使用 $function 获取请求的主要内容,如果未能解决你的问题,请参考以下文章

在 MongoDB 中存储 GeoJSON 多边形

mongodb.open is not a function

使用TS封装操作MongoDB数据库的工具方法

使用 mongodb 设计 gps 时间序列数据的数据库

单链查询 mongodb / mongoose 获取所有评论

Mongodb 如何使用 C# 驱动程序更新许多文档