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

从MongoDB查询元素索引始终返回-1的问题求助

问题:Territory数组中查找当前元素索引始终返回-1

在Territory详情页实现「上一个/下一个」切换功能时,尝试在控制器中查找当前Territory在数组中的索引,结果始终返回-1,但用console.log输出数组时明明能看到目标元素存在。

当前控制器代码:

export const renderTerritoryHistory = (req, res, next) => {
    Territory
        .findById(req.params.territory_id)
        .populate(["preacher", "history"])
        .exec()
        .then((territory) => {
            Territory
                .find({congregation: req.user._id})
                .exec()
                .then((territories) => {
                    console.log(territories);
                    const currentIndex = territories.findIndex(t => t._id === mongoose.Types.ObjectId(territory._id));
                    console.log(currentIndex);
                    res.render("./territories/show", {
                        header: `Teren nr ${territory.number} | Territory Manager`,
                        territory: territory,
                        countDaysFromNow: countDaysFromNow,
                        currentUser: req.user,
                        currentIndex: currentIndex,
                        territories: territories
                    })
                })
                .catch((err) => console.log(err))
        })
        .catch((err) => console.log(err))
}

问题原因

核心问题是ObjectId的比较逻辑错误:

  • Mongoose返回的_id是ObjectId对象,不是普通字符串。直接用===比较两个ObjectId对象,哪怕它们的值完全相同,也会因为是不同的对象引用而返回false。
  • 你额外把territory._id转成新的mongoose.Types.ObjectId实例,这会生成一个全新的对象,和数组里的t._id引用完全不匹配,自然找不到索引。

解决方案

方案1:使用ObjectId的equals()方法(推荐)

Mongoose的ObjectId实例自带equals()方法,专门用来比较两个ObjectId的值是否相等:

const currentIndex = territories.findIndex(t => t._id.equals(territory._id));

方案2:转成字符串后比较

把两个ObjectId都转换成字符串再做相等判断:

const currentIndex = territories.findIndex(t => t._id.toString() === territory._id.toString());

方案3:优化查询逻辑(减少数据库请求)

可以合并两次查询,先获取所有符合条件的Territory,再从中定位当前项并填充关联数据,减少一次数据库调用:

export const renderTerritoryHistory = (req, res, next) => {
  Territory.find({ congregation: req.user._id })
    .exec()
    .then((territories) => {
      // 先找到当前Territory
      const currentTerritory = territories.find(t => t._id.equals(req.params.territory_id));
      if (!currentTerritory) {
        return res.status(404).send('Territory not found');
      }
      // 填充关联数据
      return currentTerritory.populate(["preacher", "history"])
        .then(territory => {
          const currentIndex = territories.findIndex(t => t._id.equals(territory._id));
          res.render("./territories/show", {
            header: `Teren nr ${territory.number} | Territory Manager`,
            territory: territory,
            countDaysFromNow: countDaysFromNow,
            currentUser: req.user,
            currentIndex: currentIndex,
            territories: territories
          });
        });
    })
    .catch((err) => console.log(err));
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:55:22