db.eval聚合的异步/等待功能

时间:2018-07-24 14:18:15

标签: javascript mongodb asynchronous async-await aggregate

我正在尝试在对db.eval()的调用中执行db.collection.aggregate()查询。我使用eval()是因为要进行动态查找,因此我通过串联相关字符串来生成查询。当我手动删除字符串中的引号时,查询工作完美:

await db.collection('Products').aggregate([{
    $lookup: {
        from: 'Golomax',
        localField: 'barcode',
        foreignField: 'barcode',
        as: 'Golomax'
    }
}, {
    $unwind: {
        path: '$Golomax',
        preserveNullAndEmptyArrays: true
    }
}, {
    $lookup: {
        from: 'Masivos SA',
        localField: 'barcode',
        foreignField: 'barcode',
        as: 'Masivos SA'
    }
}, {
    $unwind: {
        path: '$Masivos SA',
        preserveNullAndEmptyArrays: true
    }
}, {
    $out: 'Output'
}]).toArray();

不幸的是,当我在对db.eval()的调用中使用字符串时,它不起作用。我在上面的代码片段两边加上了引号,并将字符串设置为等于变量“ query”,然后尝试了以下方法:

db.eval('async function(){' + query + ' return;}', function(err, result) {
      console.log('the result is: ', result);
    });

我也尝试过删除“异步”一词,但这仍然没有用。如何确保函数在返回之前完成聚合?谢谢。

-编辑-

我刚刚注意到db.eval()已被弃用并计划删除。另一种选择是“使用普通的MongoDB查询语言和客户端驱动程序API来实现等效的查询/操作”。如何使用字符串查询来做到这一点?

2 个答案:

答案 0 :(得分:0)

我刚刚使用Javascript eval()解决了自己的问题,并删除了字符串开头的“ await”。现在执行完美!

答案 1 :(得分:0)

您不需要$eval。听起来您想为数组中的每个项目创建一个$lookup$unwind。这正是map()的目的。您可以创建单独的命令数组,然后将其传递给aggregate()

// Have a list of places
const thingsToUnwind = [
  'Golomax',
  'Masivos SA',
  'Some Other Place',
  'Yet Another Place'
];

const unwindables = thingsToUnwind
  // Create a $lookup and $unwind for each place
  .map(place => {
    return [{
        $lookup: {
          from: place,
          localField: 'barcode',
          foreignField: 'barcode',
          as: place
        }
      },
      {
        $unwind: {
          path: `$${place}`,
          preserveNullAndEmptyArrays: true
        }
      }
    ];
  })
  // Flatten the array of arrays
  .reduce((acc, curr) => [...acc, ...curr], []);

// Add an $output node
unwindables.push({
  $out: 'Output'
});

// Perform the aggregation
await db
  .collection('Products')
  .aggregate(unwindables)
  .toArray();