How can I store GeoJSON location when it is not provided or empty? I tried setting the location to null but it gives following error
MongoError: Can't extract geo keys:{ _id: ObjectId('...'), location: { coordinates: [] } ...
Following is the code I used.
if (!data.longitude || !data.latitude) {
data.location = null;
}
else {
data.location = {
type: "Point",
coordinates: [data.longitude, data.latitude]
};
}
Simply put, don't set it at all. The problem is probably compounded by your mongoose schema. From the perspective of MongoDB, it does not care if the property simply does not exist and will subsequently ignore it in the index.
It's "mongoose" that actually creates things when you don't want to, so simply "tell it" not to include the structure if you don't provide any data:
location: {
type: { type: String },
coordinates: { type: [], default: undefined }
}
As long as the coordinates array is set to default to the undefined value, then mongoose does not attempt to add the "empty array" into the document when it persists to the database, which then would cause problems for the index.
As a full demonstration:
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()
}
})()
Which shows the stored documents as:
[
{
"location": {
"type": "Point",
"coordinates": [
151.21170043945312,
-33.86414397991936
]
},
"_id": "5af8e6c17c91d648feb26cc4",
"name": "Sydney",
"__v": 0
},
{
"_id": "5af8e6c17c91d648feb26cc5",
"name": "Nowhere",
"__v": 0
}
]
So if you don't actually supply any location data, then there's simply nothing there. Which makes MongoDB happy because there is not invalid data in the property to be indexed for the "2d" or "2dsphere".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With