mongoose mongoDB中的NestJS GeoJSON在类型字段上出错

ncgqoxb0  于 2023-03-12  发布在  Go
关注(0)|答案(1)|浏览(125)

bounty已结束。回答此问题可获得+50声望奖励。奖励宽限期将在1小时后结束。Ryan希望引起更多人关注此问题:我需要这个问题的正确答案

我正在使用NestJS和@nestjs/mongoose创建一个需要存储GeoJSON坐标的方案。以下是位置方案的方案,其中包含一个标记为point的字段,用于存储点方案

import { Prop, Schema } from '@nestjs/mongoose';
import { ApiProperty } from '@nestjs/swagger';
    
@Schema()
export class PointSchema {
    @ApiProperty()
    @Prop({
        type: String,
        enum: ['Point'],
        default: 'Point',
        required: true
    })
    type: string
  
    @ApiProperty({
        type: [Number, Number]
    })
    @Prop({
        type: [Number, Number],
        required: true,
    })
    coordinates: number[]
}

@Schema()
export class Location {
    @ApiProperty({
        type: PointSchema
    })
    @Prop({
        type: PointSchema
    })
    point: PointSchema

    @ApiProperty()
    @Prop()
    addressShort: string;

    @ApiProperty()
    @Prop()
    addressLong: string;

    @ApiProperty()
    @Prop()
    geohash: string;
}

问题是,当我保存一个新位置时,我得到一个错误,指出点字段不能转换为对象字段,因为它是一个字符串。

  • 位置.点.类型:对于路径“point.type”,location.point.type.coordinates处的值“Point”(类型字符串),强制转换为Object失败:需要路径point.type.coordinates。*

我不确定为什么会发生这种情况,但如果我在保存对象之前更改对象形状以匹配错误所需的形状

const newLocation:Location = {
    ...location,
    point: {
        type: newPlace.location.point
    }
}

然后它会工作并将GeoJSON坐标保存在点的type字段中。我不知道为什么它试图将整个点对象保存在type字段中,我担心这将是不可索引的。有人以前经历过这种情况或使用过NestJS mongo db并尝试使用GeoJSON对象吗?谢谢。

lvmkulzt

lvmkulzt1#

Mongoose期望type作为一个对象,在你的实现中,它被定义为一个字符串,你需要改变它:

@Schema()
export class PointSchema {
    @ApiProperty()
    @Prop({
        type: {
            type: String,
            enum: ['Point'],
            default: 'Point',
            required: true,
        },
        coordinates: {
            type: [Number],
            required: true,
        },
    })
    point: {
        type: string;
        coordinates: number[];
    };
}

我不知道为什么它要尝试将整个点对象保存在type字段中
它之所以尝试将整个点对象保存在type中,是因为enumdefault属性:

@Prop({
  type: String,
  enum: ['Point'], // only accepts 'Point' as a value
  default: 'Point', // defaults to 'Point' if value is not provided
  required: true
})
type: string
  • 这些属性将type字段的可能值限制为仅'Point',如果未提供值,则还将默认值设置为'Point'
  • 当您尝试将Locationpoint一起保存时,type被设置为'Point'(这是一个字符串值)。这就是为什么会出现错误
  • 当你创建一个只包含type的新对象并对其赋值时,你创建的新对象具有enumdefault属性所期望的正确形状。这就是为什么它在你保存时有效的原因

我担心这将是不可索引的。
这取决于您计划查询的方式。

  • 如果您计划基于type进行查询,则将整个point对象保存在该字段中可能会使查询更加困难。
  • 如果您不打算基于type进行查询,那么这可能无关紧要。

只要类型字段存储为字符串而不是对象,它就应该是可索引的。

相关问题