MongoDB 中位置为空时如何存储 GeoJSON

San*_*ana 4 mongoose mongodb

当 GeoJSON 位置未提供或为空时,如何存储它?我尝试将位置设置为 null 但出现以下错误

MongoError:无法提取地理键:{ _id:ObjectId('...'),位置:{坐标:[] } ...

以下是我使用的代码。

if (!data.longitude || !data.latitude) {
    data.location = null;
}
else {
    data.location = {
        type: "Point",
        coordinates: [data.longitude, data.latitude]
    };
}
Run Code Online (Sandbox Code Playgroud)

Nei*_*unn 6

简而言之,根本不设置它。您的猫鼬模式可能会加剧该问题。从 MongoDB 的角度来看,它并不关心该属性是否根本不存在,并且随后会在索引中忽略它。

当你不想创建东西时,“猫鼬”实际上会创建东西,所以如果你不提供任何数据,只需“告诉它”不要包含结构:

  location: {
    type: { type: String },
    coordinates: { type: [], default: undefined }
  }
Run Code Online (Sandbox Code Playgroud)

只要coordinates将数组设置default为该undefined值,那么猫鼬在保存到数据库时就不会尝试将“空数组”添加到文档中,这会导致索引出现问题。

作为完整的演示:

const { Schema } = mongoose = require('mongoose');

const uri = 'mongodb://localhost/test';

mongoose.Promise = global.Promise;
mongoose.set('debug', true);

const geoSchema = new Schema({
  name: String,
  location: {
    type: { type: String },
    coordinates: { type: [], default: undefined }
  }
});

const GeoTest = mongoose.model('GeoTest', geoSchema);


const log = data => console.log(JSON.stringify(data, undefined, 2));

(async function() {

  try {

    const conn = await mongoose.connect(uri);

    await Promise.all(Object.entries(conn.models).map(([k,m]) => m.remove()));

    await GeoTest.insertMany([
      {
        "name": "Sydney",
        "location": {
          "type": "Point",
          "coordinates": [
            151.21170043945312,
            -33.86414397991936
          ]
        }
      },
      { "name": "Nowhere" }
    ]);

    let results = await GeoTest.find();
    log(results);

  } catch(e) {
    console.error(e)
  } finally {
    process.exit()
  }

})()
Run Code Online (Sandbox Code Playgroud)

其中存储的文档显示为:

[
  {
    "location": {
      "type": "Point",
      "coordinates": [
        151.21170043945312,
        -33.86414397991936
      ]
    },
    "_id": "5af8e6c17c91d648feb26cc4",
    "name": "Sydney",
    "__v": 0
  },
  {
    "_id": "5af8e6c17c91d648feb26cc5",
    "name": "Nowhere",
    "__v": 0
  }
]
Run Code Online (Sandbox Code Playgroud)

因此,如果您实际上不提供任何location数据,那么那里就什么也没有。这让 MongoDB 很高兴,因为属性中不存在要为"2d"或建立索引的无效数据"2dsphere"