How to create Mongoose Schema for $near query - mongodb

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

How to store range(in geocircle radius form) in mongoose schema

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;

MongoDB Mongoose find using Map

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' });

How to fix MongoDB geo keys error with unknown GeoJSON type error?

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))
}

how to search for any value in the document

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

How $geoNear chooses the field of the model to find the coordenates in MongoDB?

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.