首页 > 解决方案 > Geojson 的 Mongoose 子文档

问题描述

我无法定义正确的可重用点模式。我刚刚复制了https://mongoosejs.com/docs/geojson.html中的示例架构

这是我在启动 node.js 应用程序时遇到的错误

/home/******/projects/realista-api/node_modules/mongoose/lib/schema.js:418 throw new TypeError('Invalid value for schema path ' + prefix + key + ''); ^ TypeError:架构路径的值无效coordinates

我已经尝试过使用不可重用的模式。通过直接在父模式中定义它并且它可以工作

coordinates: {
    type: {
      type: String,
      enum: ['Point'],
      required: true
    },
    coordinates: {
      type: [Number],
      required: true
    }
  },

这是代码

import { Schema, Document } from 'mongoose';

interface Point extends Document {
  type: string,
  coordinates: Array<number>,
}

const PointSchema: Schema = new Schema({
  type: {
    type: String,
    enum: ['Point'],
    required: true
  },
  coordinates: {
    type: [Number],
    required: true
  }
}, {
  id: false
});

export {
  Point,
  PointSchema,
}

我在另一个模式中使用它作为子文档

const ProjectSchema: Schema = new Schema({
  owner: {
    type: Schema.Types.ObjectId,
    ref: 'User',
    required: false,
  },
  logo: {
    type: String,
    required: false,
  },
  name: {
    type: String,
    required: true,
  },
  location: {
    type: String,
    required: false,
  },
  suburb: {
    type: String,
    required: false,
  },
  stateCode: {
    type: String,
    required: false,
  },
  country: {
    type: String,
    required: false,
  },
  countryName: {
    type: String,
    required: false,
    unique: true,
    sparse: true,
  },
  coordinates: PointSchema,// this is the field in question
  commission: {
    type: Schema.Types.Decimal128,
    required: false,
  },
  tax: {
    type: Schema.Types.Decimal128,
    required: false,
  },
  propertyType: {
    type: Schema.Types.ObjectId,
    ref: 'PropertyType',
    required: true,
  },
  address: {
    type: String,
    required: false,
  },
  title: {
    type: String,
    required: false,
  },
  description: {
    type: String,
    required: false,
  },
  videoTour: {
    type: String,
    required: false,
  },
  matterPortUrl: {
    type: String,
    required: false,
  },
  currency: {
    type: String,
    required: false,
  },
  minPrice: {
    type: Schema.Types.Decimal128,
    required: false,
  },
  maxPrice: {
    type: Schema.Types.Decimal128,
    required: false,
  },
  otherPrice: {
    type: String,
    required: false,
  },
  featureLandSizeMin: {
    type: String,
    required: false,
  },
  featureLandSizeMax: {
    type: String,
    required: false,
  },
  featureLandSizeUnit: {
    type: String,
    required: false,
  },
  featureBuiltStart: {
    type: Date,
    required: false,
  },
  featureBuiltEnd: {
    type: Date,
    required: false,
  },
  featureNumOfLevel: {
    type: Number,
    required: false,
  },
  featureNumOfUnit: {
    type: Number,
    required: false,
  },
  featureFlooring: {
    type: String,
    required: false,
  },
  featureExterior: {
    type: String,
    required: false,
  },
  featureConcierge: {
    type: String,
    required: false,
  },
  indoorFeatures: {
    type: String,
    required: false,
  },
  outdoorFeatures: {
    type: String,
    required: false,
  },
  minBedrooms: {
    type: Number,
    required: false,
  },
  maxBedrooms: {
    type: Number,
    required: false,
  },
  minBathrooms: {
    type: Schema.Types.Decimal128,
    required: false,
  },
  maxBathrooms: {
    type: Schema.Types.Decimal128,
    required: false,
  },
  minParking: {
    type: Number,
    required: false,
  },
  maxParking: {
    type: Number,
    required: false,
  },
  csvVariationPending: {
    type: Boolean,
    required: false,
    default: false,
  },
  isPrivate: {
    type: Boolean,
    required: false,
    default: false,
  },
  status: {
    type: Boolean,
    required: false,
    default: false,
  },
  variations: [{
    type: Schema.Types.ObjectId,
    ref: 'ProjectVariation',
  }],
  deletedAt: {
    type: Date,
    required: false,
  }
}, {
  collection: 'projects',
  timestamps: true,
  strict: false,
});

我究竟做错了什么?提前致谢。

标签: node.jsdatabasemongodbmongoose

解决方案


能够使它工作。希望这对使用 node.js 进行开发的其他人有所帮助

这个问题是由两件事引起的:

  1. Mongoose 在声明子文档(嵌套对象或对象数组)时,当type文档中有字段时会感到困惑,因为在 Mongoose 概念中,它是声明字段类型的保留字。就我而言,type密钥来自GeoJSON,因为 MongoDB 要求它采用该格式。这是来自 mongoose文档的链接,以便更好地理解。

我刚刚做的就是把 PointSchema 改成这个

import { Schema, Document } from 'mongoose';

interface Point extends Document {
  type: string,
  coordinates: Array<number>,
}

const PointSchema: Schema = new Schema({
  type: {
    $type: String,
    enum: ['Point'],
    required: true
  },
  coordinates: {
    $type: [Number],
    required: true
  }
}, {
  _id: false,
  typeKey: '$type',
});

export {
  Point,
  PointSchema,
}
  1. 在导入/需要 PointSchema 时,我在 node.js 中也遇到了循环依赖问题。这个错误
/home/******/projects/realista-api/node_modules/mongoose/lib/schema.js:418 throw new TypeError('Invalid value for schema path ' + prefix + key + ''); ^ TypeError: Invalid value for schema path coordinates

发生是因为我在 ProjectSchema 中使用 PointSchema 时未定义它。

W/c 证明了为什么 Mongoose Github 中的问题表明,大多数情况下,当他们遇到该错误时,这是​​因为类型拼写错误(ObjectID 而不是 ObjectId),或者在我的情况下,未定义的 w/c 是无效类型。


推荐阅读