更新 mongoose 子文档会修改原始模式

Posted

技术标签:

【中文标题】更新 mongoose 子文档会修改原始模式【英文标题】:Updating a mongoose sub-document modifies the original schema 【发布时间】:2016-10-03 17:01:47 【问题描述】:

我正在尝试将停车场Spotlocation 存储在单个嵌入式子文档中,以获得更清晰的对象模型。对于每个新的Spot,我希望将locationcoordinates 用于Spot 默认为[]

当我按如下方式创建 Schema 时:

var LocationSchema = new Schema(
  Coordinates: 
    type: [Number],
    index: '2dsphere'
  
)

然后将该 Schema 作为子文档嵌入到Spot

var SpotSchema = new Schema(
  location: 
    type: LocationSchema,
    default: LocationSchema
  
)

var Spot = mongoose.model('Spot', SpotSchema')

然后实例化一个Spot 并尝试将它的coordinates 设置为某个值,例如[12, 34]

var spot = new Spot()
spot.location.coordinates = [12, 34]

从那时起,我实例化的每个新 Spot 的坐标都默认为该值:

var anotherSpot = new Spot()
anotherSpot.location.coordinates //returns [12, 34]

我做错了什么?我不明白为什么修改实例的属性会修改原始模型以及由此创建的每个新实例。

编辑

即使不使用子文档也会出现完全相同的问题:

var SpotSchema = new Schema(
    location: 
        type: 
            coordinates: [Number],
            index: '2dsphere'    
        ,
        default: 
            coordinates: []
        
    
 )

var Spot = mongoose.model('Spot', SpotSchema')

var spot = new Spot()
spot.location.coordinates = [12, 34]
var anotherSpot = new Spot()
anotherSpot.location.coordinates //returns [12, 34]

【问题讨论】:

【参考方案1】:

我认为这就是你想要的(使用你的最后一个例子):

var SpotSchema = new Schema(
    location: 
      type        : String,
      coordinates :  
        $type   : [ Number ],
        default : [],
        index   : '2dsphere'
      ,
    
 ,  typeKey : '$type' )

type 在 Mongoose 中“保留”;如果您需要创建具有该名称的属性,则需要使用 typeKey 告诉 Mongoose 它应该使用另一个标识符来声明属性的类型(在本例中为 $type)。

解释了here,包括对 GeoJSON 用法的引用。

【讨论】:

我试过了,还是不行,spot.location.coordinatesundefined 我认为[] 可能不是有效的默认值。 (或者更确切地说,与 index : '2dsphere' 结合使用时没有意义,因此 Mongoose 不会填充它) 您能否向我解释/指向一篇文章来解释为什么默认设置没有意义?看来我的谷歌技能低于标准,因为我一直在寻找更多关于 mongoose indexs 和 geoJSON 在 mongoose 中使用的信息,显然我仍然不知道如何使用它们 如果删除索引声明,Mongoose 填充坐标数组,所以我猜对 Mongoose 来说,默认为空数组是没有意义的 :-) MongoDB不会索引具有空坐标或null 坐标(记录在here)的 GeoJSON 文档,也许它也与此有关。

以上是关于更新 mongoose 子文档会修改原始模式的主要内容,如果未能解决你的问题,请参考以下文章

未能成功更新 Mongoose 子文档

更新子文档、NodeJS 和 Mongoose 的更有效方式

更新子文档、NodeJS 和 Mongoose 的更有效方式

Mongoose - 使用 findOneAndUpdate 更新子文档

Mongoose如何更新子文档字段?

Mongoose 不会更新子文档