You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Node.js的MongoDB聚合按指定顺序返回数据?

解决MongoDB按选择顺序返回卡牌数据的问题

你的问题核心有两个:

  • find方法返回的结果默认不是$in数组的顺序,而是MongoDB的自然排序(或按索引排序)
  • aggregate方法没返回数据,是因为输入的字符串类型和数据库中数字类型不匹配:req.body里的参数是字符串,而数据库的zahl是数字,$indexOfArray无法匹配,导致没有结果。

下面给出两种可行的解决办法:

方法一:修正Aggregate的类型匹配

把输入的字符串转成数字,同时调整投影的写法(aggregate的投影需用$project阶段),修改后的代码如下:

router.post('/cards', (req, res) => {
  // 将请求参数转为数字类型,匹配数据库的字段类型
  let zahl1 = parseInt(req.body.zahl1);
  let zahl2 = parseInt(req.body.zahl2);
  let zahl3 = parseInt(req.body.zahl3);
  let zahls = [zahl1, zahl2, zahl3];
  
  cards.aggregate([
    // 匹配符合条件的卡牌
    { "$match": { "zahl": { "$in": zahls } } },
    // 给每条数据添加对应输入顺序的索引
    { "$addFields": { "__order": { "$indexOfArray": [zahls, "$zahl"] } } },
    // 按索引排序
    { "$sort": { "__order": 1 } },
    // 排除_id字段
    { "$project": { _id: 0 } }
  ]).exec((err, cards) => {
    if (err) {
      return res.json({ success: false, error: err.message });
    }
    return res.json({
      success: true,
      cards: cards,
      zahls: zahls
    });
  });
});

方法二:Find查询后在代码层排序

如果觉得aggregate逻辑复杂,也可以先用find拿到所有匹配数据,再在代码里按照输入顺序重新排列,适合数据量小的场景(比如你这里最多3张卡牌):

router.post('/cards', (req, res) => {
  let zahl1 = parseInt(req.body.zahl1);
  let zahl2 = parseInt(req.body.zahl2);
  let zahl3 = parseInt(req.body.zahl3);
  let zahls = [zahl1, zahl2, zahl3];
  
  cards.find({ "zahl": { "$in": zahls } }, { _id: 0 }).exec((err, cards) => {
    if (err) {
      return res.json({ success: false, error: err.message });
    }
    // 根据输入的zahls顺序,重新映射结果数组
    const orderedCards = zahls.map(targetZahl => 
      cards.find(card => card.zahl === targetZahl)
    );
    return res.json({
      success: true,
      cards: orderedCards,
      zahls: zahls
    });
  });
});

两种方法都能实现你想要的效果:输入30、5、25时,返回的卡牌顺序和选择顺序一致。

内容的提问来源于stack exchange,提问作者kangaroo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:40:18