I have create a collection on MongoDB with with geo index "2dsphere" and I have an element with this structure in my colelction:
{
"_id" : ObjectId("573b2416130380fbf20c2610"),
"location" : {
"type" : "Point",
"coordinates" : [ -73.856077, 40.848447 ]
},
"marca" : "smart",
"stato" : "libera"
}
How can I create a schema in mongoose for this strucuture?
Assuming the collection is named Location, you could either define your schema as:
var locationSchema = new mongoose.Schema({
marca: { type: String, required: true },
stato: { type: String, required: true },
loc: {
type: {
type: "String",
required: true,
enum: ['Point', 'LineString', 'Polygon'],
default: 'Point'
},
coordinates: [Number]
}
});
locationSchema.index({'loc': '2dsphere'});
var Location = mongoose.model('Location', locationSchema);
or with the index:
var locationSchema = new mongoose.Schema({
marca: { type: String, required: true },
stato: { type: String, required: true },
loc: {
type: {
type: "String",
required: true,
enum: ['Point', 'LineString', 'Polygon'],
default: 'Point'
},
coordinates: [Number],
index: { type: '2dsphere', sparse: true }
}
});
var Location = mongoose.model('Location', locationSchema);
Related
I am building an e-commerce application. Every store has a delivery range so i want to set delivery range of every store in the database to show the store only to those who falls in the delivery range.
Store Schema.
const mongoose = require("mongoose");
const sellerSchema = new mongoose.Schema({
name:{
type: String,
required: true,
},
type: {
type: String,
required: true
},
location: {
type: {
type: "String",
enum:['Point']
},
coordinates: {
type: [Number],
index: '2dsphere'
}
},
owner: {
type: String,
required: true
},
items: [{
type: mongoose.Schema.Types.ObjectId,
ref: "items"
}],
contact: {
type: String,
required: true
},
loginId: {
index:true,
unique: true,
type: String,
},
password: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
}
});
const sellerModel = mongoose.model("sellers",sellerSchema);
module.exports = sellerModel;
I have a mongoose schema like this:
const userSchema = new Schema( {
email:{ type: String, required: true, unique:true, index:true },
mobile:{ type: String },
phone:{ type: String },
firstname: { type: String },
lastname: { type: String },
profile_pic:{type:String},
socialHandles: {
type: Map,
of: String
},
active: {type:Boolean, default:true}
}, {
timestamps: true
} );
I want to query "give me user where socialHandles.instagram=jondoe" how do I do it?
Please help
Mongoose's map becomes a nested object in your database
{ "_id" : ObjectId(""), "socialHandles" : { "instagram": "jondoe" }, ..., "__v" : 0 }
so you can query it by using the dot notation:
let user = await User.findOne({ 'socialHandles.instagram': 'jondoe' });
I'm receiving the following error when running a query in Mongo:
"errmsg" : "Can't extract geo keys: …[removed unnecessary elements]… unknown GeoJSON type: { coordinates: [ -75.17886559999999, 39.9451937 ] }
I've updated the schema to include 2dsphere, per the below:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
mongoose.promise = Promise;
const listingSchema = new Schema({
user: { type: Schema.Types.ObjectId, ref: "User" },
title: { type: String, unique: false, required: false },
parkingtype: { type: String, unique: false, required: false },
photo: { type: String, unique: false, required: false },
price: { type: Number, unique: false, required: false },
address: { type: String, unique: false, required: false },
city: { type: String, unique: false, required: false },
state: { type: String, unique: false, required: false },
zipcode: { type: Number, unique: false, required: false },
streetName: { type: String, unique: false, required: false },
neighborhood: { type: String, unique: false, required: false },
location: {
type: {
type: String,
enum: ['Point'],
required: false
},
coordinates: {
type: [Number]
}
}
});
listingSchema.index({location: '2dsphere'}); // <-- already added index
const Listing = mongoose.model("Listing", listingSchema);
module.exports = Listing;
This is the error I get back in my terminal (see bold):
errmsg:
'error processing query: ns=parky.listingsTree: GEONEAR field=location maxdist=2000 isNearSphere=0\nSort: {}\nProj: {}\n planner returned error :: caused by :: unable to find index for $geoNear query',
code: 291,
codeName: 'NoQueryExecutionPlans',
name: 'MongoError',
[Symbol(mongoErrorContextSymbol)]: {} }
Finally, for reference, this is my controllers file, and the query that is being run:
findAllNear: function(req, res) {
var long = req.query.data[0]
var lat = req.query.data[1]
var floatLong = parseFloat(long); // longitude comes through as string from url params, so it's converted to a float
var floatLat = parseFloat(lat); // same with latitude
db.Listing.syncIndexes().then((index) => {
console.log("indexes:" , index);
}); // added this snippet to see that the location index was 2d
db.Listing.find(
{location:
{$near:
{$maxDistance: 2000,
$geometry: {
type: "Point",
coordinates: [floatLong, floatLat]
}
}
}
})
.find((error, results) => { if (error) console.log(error);
console.log(JSON.stringify(results, 0, 2))})
.then(data => res.json(data))
.catch(err => res.status(422).json(err))
}
I want to search for all value present without specifying key explicitly. Is it possible with this type of schema? If so, how can I write my query. I tried to write query with other refs but I am unable to write without specifying key for each.
const pschema = new Schema({
user: {
type: Schema.Types.ObjectId, // combine by id
ref: "users" //existing model reference
},
company: {
empNo: {
type: Number,
required: true
},
status: {
type: String,
required: true
},...
},
personal: {
gender: {
type: String
},
dob: {
type: Date
},...
},
skills: {
type: [String],
required: true
},
experience: [
{
title: {
type: String,
required: true
},
company: {
type: String,
required: true
},
location: {
type: String
}...
}
],
education: [
{
school: {
type: String,
required: true
},
degree: {
type: String,
required: true
},
specialization: {
type: String
},..
}
],
social: {
twitter: {
type: String
},
facebook: {
type: String
},
linkedin: {
type: String
},...
}
});
For example: If i give linkedin url if should search in social-linkedin and same if i give c it should search in skills array
I'm using mongoose and I'm trying to get activities from the schema 'Activity' with an specific filter using $geoNear, but it always returns an empty array and I think it's because the aggregate function is not finding the coordenates of my model.
This is an example of the JSON to send:
{
"coordinates": {
"lat": 37.3890924,
"lon": -5.984458899999936
},
"distance": 100000000
}
This is the query:
Activity.aggregate([
{ $geoNear: {
near: {
type: "Point",
coordinates: [req.body.coordinates.lon, req.body.coordinates.lat]
},
maxDistance: req.body.distance * 1000,
spherical: true,
distanceField: "distance"
}
}
])
And this is the schema, where the coordinates are into the field 'meetingPoint':
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate');
const Schema = mongoose.Schema;
var ActivitySchema = Schema({
title: {type: String, require: true },
meetingPoint: {
meet_name:{type: String, require: true },
coordinates: {
lat: {type: Number, require: true },
lon: {type: Number, require: true }
}
},
date: {type: Date, require: true },
car: Boolean,
sites: {type: Number, min: 0 },
price: {type: Number, min: 0.0, require: true },
description: String,
eventTime: String,
event: Boolean,
sport: {type: Schema.Types.ObjectId, ref: 'Sport', require: true },
owner: {type: Schema.Types.ObjectId, ref: 'User', require: true },
attenders: [{type: Schema.Types.ObjectId, ref: 'User'}],
comments: [{type: Schema.Types.ObjectId, ref: 'Comment'}],
ratings: [{
rating:{type: Number},
user: {type: Schema.Types.ObjectId, ref:'User'}
}],
creationDate: {type: Date, default: Date.now, require: true },
updateDate: {type: Date, default: Date.now, require: true },
public: Boolean,
image: String
});
ActivitySchema.plugin(mongoosePaginate);
ActivitySchema.index({location: "2dsphere"});
module.exports = mongoose.model('Activity', ActivitySchema);
EDIT: I changed the coordinates in mongoose schema to the GeoJSON format(I think) and now they look like this:
meetingPoint: {
meet_name:{type: String, require: true },
coordinates: {
type: String,
coordinates: []
}
}
But the result is the same.
EDIT2: I also updated the existing data in the collection according to the meetingPoint with the pertinent format. This is an example:
"_id" : ObjectId("5ac36a2aasdsd3242b"),
"meetingPoint" : { "meet_name" : "Av. de Menéndez Pelayo, 76, 41030 Madrid, España", "coordinates" : { "type" : "Point", "coordinates" : [ -5.984458899
9936, 37.3890924 ] } },
"attenders" :....
But I still receive no activities with the filter.