Javascript 使用Mongoose.lean()方法进行相等性测试失败

Javascript 使用Mongoose.lean()方法进行相等性测试失败,javascript,node.js,mongodb,express,mongoose,Javascript,Node.js,Mongodb,Express,Mongoose,我试图将req.user.\u id与从MongoDB查询返回的ObjectID数组进行比较。但所有.includes()、严格和松散的相等性检查均失败 以下是我的控制器中的逻辑(为简单起见,将其截断): //从请求中获取文档的ID const someDocId=req.body.id; //使用投影执行搜索 const result=wait Some_DB.findById(someDocId,{adminIds:1,_id:0}).lean(); /* 查询结果的结构如下: { 管理员I

我试图将
req.user.\u id
与从MongoDB查询返回的ObjectID数组进行比较。但所有
.includes()
、严格和松散的相等性检查均失败

以下是我的控制器中的逻辑(为简单起见,将其截断):

//从请求中获取文档的ID
const someDocId=req.body.id;
//使用投影执行搜索
const result=wait Some_DB.findById(someDocId,{adminIds:1,_id:0}).lean();
/*
查询结果的结构如下:
{
管理员ID:[5F77BA7D1A0FBA8F5E811E766035F2E7174D4961808944D1],
}
和请求用户id等于6035f2e7174d4961808944d1
*/
//当我这样做的时候
console.log(result.adminIds[1]==req.user.\u id);
console.log(result.adminIds[1]==req.user.\u id);
日志(result.adminIds.includes(req.user.\u id))
//我也试过了
const{ObjectId,}=require('mongoose')。类型
console.log(result.adminIds[1]==ObjectId(请求用户id));
console.log(result.adminIds[1]==ObjectId(req.user.\u id));
log(result.adminIds.includes(ObjectId(req.user.\u id)))
//结果总是错误的
//其他信息:
(以下结果与带或不带.lean()的结果相同)
const{ObjectId,}=require('mongoose')。类型
常数a=sphereInfo.adminIds[1];
const b=请求用户\u id;
console.log(ObjectId的实例);//=>true
console.log(ObjectId的b实例);//=>true
console.log(typeof(result.adminIds[1]);//=>对象
console.log(typeof(req.user._id));//=>对象
console.log(result.adminIds[1]);
//6035f2e7174d4961808944d1(注意:没有单独的报价)
控制台日志(请求用户id);
//6035f2e7174d4961808944d1(注意:没有单独的报价)
const a=Object.values(sphereInfo.adminIds[1]);
常量b=对象值(请求用户id);
console.log(a);//=>
console.log(b);//=>
const a=Object.getOwnPropertyNames(sphereInfo.adminIds[1]);
const b=Object.getOwnPropertyNames(请求用户id);
console.log(a);//=>
console.log(b);//=>
log(Object.entries(sphereInfo.adminIds[1]);
控制台日志(对象条目(请求用户id));
/*
结果:
[
['\u bsontype','ObjectID'],
[‘id’,]
]
[
['\u bsontype','ObjectID'],
[‘id’,]
]
*/
log(JSON.stringify(sphereInfo.adminIds[1]);
log(JSON.stringify(req.user._id));
/*
结果:
“6035f2e7174d4961808944d1”
“6035f2e7174d4961808944d1”
*/
//删除.lean()后
console.log(result.adminIds[1]==req.user.\u id);//=>false
console.log(result.adminIds[1]==req.user.\u id);//=>false
console.log(result.adminIds.includes(req.user.\u id))/=>true
架构(为简单起见,已截断):

//依赖项
const mongoose=require('mongoose');
const Schema=mongoose.Schema;
//创建模式
const SomeSchema=新模式({
管理员ID:[{
类型:Schema.Types.ObjectId,
ref:'用户',
}],
}, {
集合:“SomeCollection”,
时间戳:对,
});
module.exports={SomeSchema,};
无论从哪个角度看,它们都是完全相同的。但是,所有
.includes()
、strict和lose相等性检查都返回false。更让我困惑的是,对象结构在有无
.lean()
的情况下都是相同的 如果我从查询中删除
.lean()
,所有检查仍然失败,只有
.inclides()
返回true。 根据猫鼬的说法:

精益选项告诉Mongoose跳过对结果文档的水合作用。这使得查询速度更快,内存占用更少,但结果文档是普通的旧JavaScript对象(POJO),而不是Mongoose文档。默认情况下,Mongoose查询返回Mongoose文档类的实例。文档比普通JavaScript对象重得多,因为它们有很多用于更改跟踪的内部状态。启用精益选项告诉Mongoose跳过实例化完整Mongoose文档,只给您POJO

文档还提到,启用精益的缺点是精益文档没有:

  • 变更跟踪
  • 铸造和验证
  • 接球手和接球手
  • 虚拟的
  • 保存()
我看不出
.lean()
会影响相等性检查以及
.includes()
方法。 最后一个问题是,有人能向我解释一下
.lean()
是如何导致平等性检查失败的,而
.includes
是如何通过的吗?
注意:我不是问如何比较它们以便检查通过,而是问
.lean()
如何导致检查失败,但“.includes()通过。我不完全清楚为什么文档坚持它们是POJO,但您得到的结果确实与对象匹配。也许他们说它们是POJO,因为它们不是由相关构造函数构造的,它们只是传递给新对象的属性

如果要比较控制台上显示的十六进制值,则需要比较
str
属性

console.log(result.adminIds[1].str === req.user._id.str);
否则,您将比较两个不同的对象(这总是错误的)

这将检查为真的唯一方法是:

console.log(result.adminIds[1] === req.user._id);
如果它们都是相同的对象,或者它们都是相同的字符串

在我看来


我不会将扩展
valueOf
和/或
toString
的对象称为POJO,因为它本质上是扩展JS对象的一些功能。因此,不再简单。

我不完全确定为什么文档坚持它们是POJO,但您得到的结果与对象匹配。也许他们说它们是POJO因为它们不是由相关构造函数构造的,它们只是传递给新对象的属性

如果要比较控制台上显示的十六进制值,则需要比较
str
属性

console.log(result.adminIds[1].str === req.user._id.str);
否则,您将比较两个不同的对象(始终为f)
console.log(result.adminIds[1].toString() === req.user._id.toString());
indexOf(obj, fromIndex) {
  if (obj instanceof ObjectId) {
    obj = obj.toString();
  }

  fromIndex = fromIndex == null ? 0 : fromIndex;
  const len = this.length;
  for (let i = fromIndex; i < len; ++i) {
    if (obj == this[i]) {
      return i;
    }
  }
  return -1;
}