I want a list of Lawyers nearby,
I have used MongoDB aggregation but it gives results only if I pass maxDistance greater than 100km.
if I want to set maxDistance = 10 * 1000; then it is not giving any result but there are data available in the database.
this is model :
const mongoose = require('mongoose')
const Schema = mongoose.Schema;
const lawyerSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
location: {
type: { type: String, default: 'Point' },
coordinates: { type: [Number], default: [0, 0] }
}
})
lawyerSchema.index({ "location": "2dsphere" });
const Lawyer = mongoose.model('Lawyer', lawyerSchema)
module.exports = Lawyer
This is route :
//route for find nearby lawyer
router.get("/findLawyer", (req, res) => {
const long = parseInt(req.query.long);
const lat = parseInt(req.query.lat);
Lawyer.aggregate(
[
{
$geoNear: {
near: {
type: "Point",
coordinates: [long, lat],
},
distanceField: "dist",
minDistance: 10 * 1000,
maxDistance: 10 * 1000,
distanceMultiplier: 6371,
spherical: true,
key: "location",
},
},
],
(err, results) => {
if (err) {
res.status(400).json({ error: err });
} else {
res.status(200).json({ result: results });
}
}
);
});
This is record inside database :
This is my postman :
correct me if I made any mistake.
Thanks
Related
I created an API using Nodejs and mongoose,
app.js
const express = require('express')
mongoose = require('mongoose')
var cron = require('node-cron');
const app = express()
app.use(cors());
const port = 3000
bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Duser = require('./models/duser.Model');
cron.schedule('* 12 * * *', () => {
console.log("corn shedule");
Duser.updateMany({"devices.validity": {$gt: 0}}, {$inc: {"devices.$[].validity": -1}}, function(err) {
if(err)
{
console.log(err);
}
});
});
I update all validity decrement by 1, if validity is greater than zero but the condition is not working, the value is decrement by 1 it goes negative value. help me solve the problem
Duser.Model.js
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Schema = new Schema({
phone_number: { type: String, Required: 'Phone Number cannot be left blank.' },
email: { type: String, Required: 'email cannot be left blank.' },
user_name: { type: String, Required: 'Customer Name cannot be left blank.'},
date: { type: Date, default: Date.now },
"devices": {
"type": [
{
ime_number: { type: String, Required: 'IME Number cannot be left blank.'},
device_name: { type: String, Required: 'Device Name cannot be left blank.'},
subscription_type: { type: String, Required: 'Subscription Type cannot be left blank.'},
validity: { type: Number, Required: 'Validity cannot be left blank.'},
date: { type: Date, default: Date.now },
}
]
}
}, { versionKey: false });
module.exports = mongoose.model('DUsers', Schema);
Try to reference the type attribute and use $elemMatch for filtering the subarray elements
cron.schedule('* 12 * * *', () => {
console.log('corn shedule');
Duser.updateMany(
{ 'devices.type': { $elemMatch: { validity: { $gt: 0 } } } },
{ $inc: { 'devices.type.$[].validity': -1 } },
function (err) {
if (err) {
console.log(err);
}
}
);
});
This question already has answers here:
Find a Location within a stored Circle
(2 answers)
Ambiguity about $geoNear in aggregate query
(1 answer)
Closed 3 years ago.
Currenty I'm working with MongoDB and I have a users collection with the following schema:
const DEFAULT_JOB_RADIUS = 5000 // In meters
const settingsSchema = new Schema({
jobRadius: {
type: Number,
default: DEFAULT_JOB_RADIUS
}
})
const userSchema = new Schema({
firstName: {
trim: true,
type: String
},
lastName: {
trim: true,
type: String
},
email: {
trim: true,
type: String,
unique: true
},
password: {
type: String
},
token: {
type: String
},
fcmToken: {
type: String
},
lastLocation: {
type: pointSchema
},
settings: {
type: settingsSchema,
default: settingsSchema
}
}, {
timestamps: true
})
Point schema looks like this:
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const pointSchema = new Schema({
type: {
type: String,
enum: ['Point'],
default: 'Point'
},
coordinates: {
type: [Number],
default: [0, 0],
index: '2dsphere'
}
});
module.exports = pointSchema
Every user has a jobRadius property. This property represents the max distance of the user to any point.
In my code, I need to fetch all the users that are near a specific point.
Here is what I'm currently trying to do:
async getNearbyUsers(point) {
const users = await this.model.aggregate([
{
$geoNear: {
near: point,
distanceField: "dist.calculated",
maxDistance: '$settings.jobRadius',
spherical: true
}
}
])
return users
}
This code doesn't work. It always bring me all the users inside the collection.
If I change the maxDistance field to something like that, it works:
maxDistance: 1
My questions is - How can I perform such aggregation, where the max distance is dynamic and specific to each user?
Ok so I managed to solve this, with the help of #Ashh
I first calculate the distance between the users and the point and then I filter all the users that their radius property exceeds the distance.
async getNearbyUsers(point) {
const users = await this.model.aggregate([
{
$geoNear: {
near: point,
distanceField: "dist.calculated",
spherical: true
}
},
{
$match: {
$expr: {
$gt: ['$settings.jobRadius', '$dist.calculated']
}
}
}
])
return users
}
I have set of products indexed in elasticsearch. I`m searching for "title" on my schema.
When I search "fre" or "fresh" I see a result.
But when I search for "small fresh" I don't see any result.
Is it possible to use wildcard with spaces ?
I added es_indexed: "not_analyzed" but no luck.
This is my Product Schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
var mongoosastic = require("mongoosastic");
const deepPopulate = require("mongoose-deep-populate")(mongoose);
var Owner = require("./user");
var Category = require("./category");
var Reviews = require("./review");
const ProductSchema = new Schema(
{
category: {
type: Schema.Types.ObjectId,
ref: "Category",
es_indexed: true,
es_type: "nested",
es_include_in_parent: true
},
owner: {
type: Schema.Types.ObjectId,
ref: "User",
es_indexed: true,
es_type: "nested",
es_include_in_parent: true
},
reviews: [
{
type: Schema.Types.ObjectId,
ref: "Review",
es_indexed: true,
es_type: "nested",
es_include_in_parent: true
}
],
image: { type: String, es_indexed: true },
title: {
type: String,
es_indexed: "not_analyzed"
},
description: { type: String, es_indexed: true },
price: { type: Number, es_indexed: true },
crated: { type: Date, default: Date.now, es_indexed: true }
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
}
);
ProductSchema.virtual("averageRating").get(function() {
var rating = 0;
if (this.reviews.length == 0) {
rating = 0;
} else {
this.reviews.map(review => {
rating += review.rating;
});
rating = rating / this.reviews.length;
}
return rating;
});
ProductSchema.plugin(deepPopulate);
ProductSchema.plugin(mongoosastic, {
populate: [{ path: "category" }, { path: "owner" }, { path: "reviews" }]
});
let Model = mongoose.model("Product", ProductSchema);
Model.createMapping(function(err, mapping) {
if (err) {
console.log("error creating mapping (you can safely ignore this)");
console.log(err);
} else {
console.log("mapping created!");
console.log(mapping);
}
});
var stream = Model.synchronize();
var count = 0;
stream.on("data", (err, doc) => {
console.log(doc);
count++;
});
stream.on("close", () => console.log("indexed " + count + " documents!"));
stream.on("error", err => console.log(err));
Model.SyncToAlgolia();
Model.SetAlgoliaSettings({
searchableAttributes: ["title"]
});
module.exports = Model;
This is my Search function
async function search(frompage) {
let fullString = "*" + "small fresh" + "*";
let startsFrom = frompage * 10;
console.log(fullString);
const response = await esClient.search({
index: "products",
type: "product",
from: startsFrom,
body: {
query: {
wildcard: {
title: fullString
}
}
}
});
return response;
}
I am getting error "Can't use $near with String error in node express" when we find records basis on longitude and latitude with maxDistance.
following is code, I am using:-
1-schema code:-
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var dtSchema = new Schema({
name:String,
date: {type: Date, default: Date.now},
location: { type: String, coordinates: [Number] },
category:String
});
//dtSchema.index({location: '2dsphere'});
module.exports = mongoose.model('places', dtSchema);
2-server.js code for fetch records
app.get('/location/:lon/:lat', function(req, res) {
console.log(req.params.lon);
console.log(req.params.lat);
location.find({location:
{ $near:
{
$geometry: { type: "Point", coordinates: [req.params.lon, req.params.lat ] },
$maxDistance: 5000
}
}}, function(err, places) {
if(!err){
res.send('({"records":' + JSON.stringify(places) + '});');
}
else{
console.log(err);
res.send("error coming")
}
});
});
parameter sending URL
http://localhost:4700/location/-73.9667/40.78
when we execute code and hit above URL. I found error "Can't use $near with String error in node express"
I had the same problem a while ago. The error is in the schema declaration.
var dtSchema = new Schema({
name:String,
date: {type: Date, default: Date.now},
location: {
type: {
type: String
},
coordinates: [Number]
},
category:String
});
db.location.aggregate([ { "$geoNear": { "near": { "type": "Point", "coordinates": [72.4468035,23.032069] }, "maxDistance": 500, "spherical": true, "distanceField": "distance" } } ])
The schema for geoNear should be
loc: {
type: {
type: String,
enum: ["Point"],
},
coordinates: {
type: [Number],
index: "2dsphere",
// 2dSphere supports queries that calculate geometries on an
// earth like sphere
},
},
i'm building an api but i'm stuck now cause i can't find a way to make geo searches
Here's the model
var Event = new Schema({
idactivites : {
type: String,
required: true,
unique: true
},
nom: String,
description: String,
location : {
type : {
type: String,
default: "Point"
},
coordinates : {
type: [Number],
index: '2d'
}
},
created: {
type: Date,
required: false,
},
modified: {
type: Date,
default: Date.now
}
});
And here's the part of the code that processes my query
app.get('/api/geo_events', function(req, res) {
var latitude = req.query.latitude;
var longitude = req.query.latitude;
var radius = req.query.radius/6371 || 5000/6371;
var limit = parseInt(req.query.limit) || 20;
if(latitude && longitude)
{
var q = EventModelModel.find({'location': {
$near: [
longitude,
latitude
],
$maxDistance: radius
}
});
}
return q.exec(function (err, events) {
if (!err) {
return res.send(events);
}
});
});
Where am I wrong ?
I did not include here the parts in case of errors, but rest assured there are in my code.
Thanks in advance,
Jeremie.