mongodb的findOne和find没有返回数据而是返回InternalCache

今天写程序,犯了一个几乎所有人都不会犯的错误,在此记录下。真是无语,因为这个错误调试了好几个小时。

背景

后端框架是egg,数据库是mongodb。需求是返回某一个用户的所有信息。

bug复现

需求很简单,我就使用findOne查找数据,但是返回的数据始终是不对。结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

{
'$__': InternalCache {
strictMode: true,
selected: {},
shardval: undefined,
saveError: undefined,
validationError: undefined,
adhocPaths: undefined,
removing: undefined,
inserting: undefined,
saving: undefined,
version: undefined,
getters: {},
_id: 64f08db9268d4c1610a8caa3,
populate: undefined,
populated: undefined,
wasPopulated: false,
scope: undefined,
activePaths: StateMachine {
paths: [Object],
states: [Object],
stateNames: [Array]
},
pathsToScopes: {},
cachedRequired: {},
session: null,
'$setCalled': Set(0) {},
ownerDocument: undefined,
fullPath: undefined,
emitter: EventEmitter {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: 0,
[Symbol(kCapture)]: false
},
'$options': { skipId: true, isNew: false, willInit: true, defaults: true }
},
isNew: false,
errors: undefined,
'$locals': {},
'$op': null,
_doc: {
role: 'admin',
_id: 64f08db9268d4c1610a8caa3,
phone: '132882xxxx',
password: '626af23deea55753ca1832a5e388f7af',
signDate: 2023-08-31T12:55:21.289Z,
vipExpireDate: 2023-08-31T12:55:21.289Z,
createDate: 2023-08-31T12:55:21.289Z,
__v: 0
},
'$init': true
}

正常情况,findone应该返回用户信息的,但是却返回了这么一个对象,数据被放在了_doc这个对象下了。这简直让人懵逼。程序里其他接口也使用了findOne,返回的是正常的,就这个接口有问题。

百度、google一顿找,也没找到原因。真是莫名其妙的就发生了量子现象。

后来加了打印日志才发现问题。代码截图如下:

image.png

bug原因

这个bug出现的原因是使用了Object.assign 复制了findone返回的user对象。 user并不是个只有key-value的js对象,它有很多自己的属性、值和方法。直接打印user,会调用user的valueOf()方法返回用户数据。但是如果使用Object.assign复制的话,会把user的所有可读属性复制过去。这时候它就变成了一个普通的js对象了,再打印的话,就是调用它的toString方法。所有打印的就不是想要的。

归根结底,就是手贱,多写了一个Object.assign