用于mongo地理位置数据的Meteor简单模式

Bel*_*dio 4 schema mongodb meteor

我想为我的meteor app创建一个管理表单; 在尝试从头构建一个之前我打算尝试Ogno Admin,但我不确定它是否能够以我需要的格式支持数据.我当前的应用数据会像这样进入mongo:

Beaches.insert({
    "name": "Entry name",
    /* location stored like this so I can use mongo $near queries */
    "location": {
        "type": "Point",
        "coordinates": [-5.0990296,50.110757]
    },
    /* could be many images, minimum 1 */
    "images": [
        {
            "url": "image1.jpg",
            "caption": "Image caption"
        }
    ],
    "shortDesc": "A delightful description...",
    /* fixed list of attributes stored as objects */
    "attributes": {
        "attr 1": {
            "score": 2,
            "text": "attr1 text"
        },
Run Code Online (Sandbox Code Playgroud)

我可以编写一个简单的模式来支持上面的不同数组/对象(尤其是位置坐标)吗?它们必须是方括号格式[lng,lat] - 并且ogno管理员可以使用它,还是我必须编写自定义管理员的东西?我可能更容易在其他东西中构建管理站点并获得它来为Meteor输出JSON数据.

更新可能的架构代码

Beaches = new SimpleSchema({
  name: {
    type: String,
  },
  location: {
    type: [Object]
  },
    location.$.type: {
    /* how do I force '"type" : "Point" into every entry?
       use 'autovalue' with the .clean() function?*/
    },
      location.$.coordinates: {
      /* how do I ensure a [x,y] array in here? */
    },
  images: {
    type: [Object]
  },
    "images.$.url": {
        type: String
    },
    "images.$.caption": {
        type: String
    },
  attributes: {
    type: [Object]
  },
  /* note that my attributes above are all prefixed with a 'name'
     eg. "attr 1" : {}
     I'm not sure how to declare these either!
  */
  ...
});
Run Code Online (Sandbox Code Playgroud)

cha*_*hne 10

嗯,我不确切地知道你保存地铁的过程的解决方案.但是如果你想保存lng和lat,你必须传递一个前缀.为什么?好的地理软件具有不同的验证范围.纬度仅在-90到90之间,经度从-180到180.如果你不保存前缀,你想如何确保哪个是哪个坐标?我有一天做错的另一个暗示是以经度,纬度顺序存储坐标.

我使用的架构如下所示:

GeocoordsSchema = new SimpleSchema({
  lng: {
    type : Number,
    decimal: true,
    min: -180,
    max: 180
  }, 
  lat: {
    type : Number,
    decimal: true,
    min: -90,
    max: 90
  }
});
Run Code Online (Sandbox Code Playgroud)

现在您创建嵌套模式.只需使用LocationSchema扩展GeocoordsSchema并添加属性即可.

LocationSchema = new SimpleSchema({
  type : {
    type : String,
    autoValue: function() {
      return "Point";
    }
  },
  coordinate: {
    type: GeocoordsSchema 
  }
});
Run Code Online (Sandbox Code Playgroud)

如果你想拥有一个LocationSchema数组,你可以在[]括号中包装模式.

BeachesSchema = new SimpleSchema({
  loc: {
    type: [LocationSchema]
  }
});
Run Code Online (Sandbox Code Playgroud)

我没有测试过,但这就是我创建和嵌套不同模式的方式.那么这个解决方案需要lat和lng的标识符.为什么不想为数据添加前缀?


Art*_*sen 6

我的解决方案就像chaosbohne,但我通过单个子架构和一些自定义验证来定义整个位置,如下所示:

SimpleSchema.messages
  lonOutOfRange: '[label] longitude should be between -90 and 90'
  latOutOfRange: '[label] latitude should be between -180 and 180'

LocationSchema = new SimpleSchema
  type:
    type: String,
    allowedValues: ['Point']
  coordinates:
    type: [Number]
    decimal: true
    minCount: 2
    maxCount: 2
    custom: ->
      return "lonOutOfRange" unless -90 <= @value[0] <= 90
      return "latOutOfRange" unless -180 < @value[1] <= 180
Run Code Online (Sandbox Code Playgroud)

在可能的情况下,我使用SimpleSchema的现有验证功能.坐标是通过minCount和限制的maxCount,虽然我可以在自定义验证功能中使用另一行.像这样的东西:

SimpleSchema.messages
  needsLatLong: '[label] should be of form [longitude, latitude]'
  lonOutOfRange: '[label] longitude should be between -90 and 90'
  latOutOfRange: '[label] latitude should be between -180 and 180'

LocationSchema = new SimpleSchema
  type:
    type: String,
    allowedValues: ['Point']
  coordinates:
    type: [Number]
    decimal: true
    custom: ->
      return "needsLatLong" unless @value.length is 2
      return "lonOutOfRange" unless -90 <= @value[0] <= 90
      return "latOutOfRange" unless -180 < @value[1] <= 180
Run Code Online (Sandbox Code Playgroud)

现在在你的例子中你会写:

Beaches = new SimpleSchema
  name:
    type: String
  location:
    type: LocationSchema
    index: '2dsphere'
  images:
    type: [Object]
  "images.$.url":
    type: String
  "images.$.caption":
    type: String
  attributes:
    type: [Object]
Run Code Online (Sandbox Code Playgroud)

请注意,index: '2dsphere'以便MongoDB知道索引类型.