如何使用Mongoose在MongoDB中存储复合对象

时间:2018-02-24 07:48:44

标签: node.js mongodb mongoose

我正在尝试在MongoDB中存储一个复合对象。该对象在MongoDB中正确存储,但在从MongoDB中取回对象时,我需要对内部Object进行类型转换而不进行类型转换,如果我尝试调用内部Object的方法,则会给出错误。

"TypeError: this.square.calculateArea is not a function".

我无法对内部对象进行Typecast,因为我不知道存储了哪个对象。在获取外部对象时,我不需要对其进行类型转换。有没有一种方法可以使用我不需要对内部对象进行类型转换。我发布下面的代码请帮忙。我用作参考的页面是https://github.com/Automattic/mongoose/issues/4356#issuecomment-236367135

'use strict';

var assert = require('assert');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost:27017/example');
mongoose.set('debug', true);

class Square {
  constructor(u) {
    this.sideA = u["sideA"];
    this.sideB = u["sideB"]
    this.sideC = u["sideC"];
    this.sideD = u["sideD"];
  }

  calculateArea() {
    return this.sideA * this.sideB * this.sideC * this.sideD;
  }

  toBSON() {
    return {
      sideA: this.sideA,
      sideB: this.sideB,
      sideC: this.sideC,
      sideD: this.sideD
    };
  }
}

class SquareSchema extends mongoose.SchemaType {
  cast(v) {
    return new Square(v);
  }
}

mongoose.Schema.Types.Square = SquareSchema;


class Polygon {
  constructor(u) {
    this.sideA = u["sideA"];
    this.sideB = u["sideB"]
    this.square = u["square"];
  }

  calculateArea() {
    var t = this.square.calculateArea(); // This line gives error.
    var k = this.sideA * this.sideB;
    return [t, k];
  }

  toBSON() {
    return {
      sideA: this.sideA,
      sideB: this.sideB,
      square: this.square
    };
  }
}

class PolygonSchema extends mongoose.SchemaType {

  cast(v) {
    return new Polygon(v);
  }
}

mongoose.Schema.Types.Polygon = PolygonSchema;

const schema = new Schema({
  test: {
    type:Polygon,
  },
  square:Square

  /*
    Tried both the above one and the below method to define schema
  */
  // test: {
  //   type:Polygon,
  //   square:Square
  // }
});

// creating a Model
const Mod = mongoose.model('Learning', schema);

// Retrieving Data from Mongoose
Mod.findOne({
  _id: "5a9111ad1303fb2bc89e2440"
}).then((data) => {
  console.log(data["test"].calculateArea());// This works without TypeCasting

});


// Inserting into MongoDB
var sq = new Square({
  sideA:5,
  sideB:6,
  sideC:7,
  sideD:8
});

var newPolygonObject = new Mod();
newPolygonObject.test = {
  sideA: 15,
  sideB: 16,
  square: sq
};

newPolygonObject.save().then(doc => {
  console.log(doc);
});

2 个答案:

答案 0 :(得分:0)

您需要在父转换函数中显式创建嵌套类的实例。

这是我的示例版本:

'use strict'

var assert = require('assert')
var mongoose = require('mongoose')
var Schema = mongoose.Schema

mongoose.connect('mongodb://localhost:27017/example')
// mongoose.set('debug', true)

class Square {
  constructor (u) {
    this.sides = u.sides
  }

  calculateArea () {
    return this.sides ** 2
  }

  toBSON () {
    return {
      sides: this.sides
    }
  }
}

class SquareSchema extends mongoose.SchemaType {
  cast (v) {
    return new Square(v)
  }
}

mongoose.Schema.Types.Square = SquareSchema

class Polygon {
  constructor (u) {
    this.sideA = u.sideA
    this.sideB = u.sideB
    this.square = u.square
  }

  calculateArea () {
    var t = this.square.calculateArea()
    var k = this.sideA * this.sideB
    return [t, k]
  }

  toBSON () {
    return {
      sideA: this.sideA,
      sideB: this.sideB,
      square: this.square
    }
  }
}

class PolygonSchema extends mongoose.SchemaType {
  cast (v) {
    let x = {
      sideA: v.sideA,
      sideB: v.sideB,
      square: new Square(v.square)
    }
    return new Polygon(x)
  }
}

mongoose.Schema.Types.Polygon = PolygonSchema

const schema = new Schema({
  poly: Polygon
})

const Mod = mongoose.model('Learning', schema)

var sq = new Square({
  sides: 5
})

var instance = new Mod({
  poly: {
    sideA: 15,
    sideB: 16,
    square: sq
  }
})

async function run () {
  await Mod.remove({})
  let saved = await instance.save()
  console.log(saved)
  let found = await Mod.findOne({ _id: instance._id })
  console.log(found.poly.calculateArea())
}

run().catch(console.error)

它的输出:

{ _id: 5ac8b37a5b220e744e1c1346,
  poly: Polygon { sideA: 15, sideB: 16, square: Square { sides: 5 }},
  __v: 0 }
[ 25, 240 ]

答案 1 :(得分:0)

听起来您想使用鉴别器(http://mongoosejs.com/docs/discriminators.html)而不是自定义架构类型。如果您不提前知道类型,那么鉴别器就是您的选择。通常,您很少需要创建自定义架构类型。