-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Working example of sort by distance with latitude/longitude and maxDistance? #230
Comments
Feathers doesn't really add a lot of magic over Mongoose. How does the Mongoose code look like? |
This code is inherited from a previous developer.
|
My 2 cents: looks like some liberal application of before hooks here might help you wrangle this code. You can always extend the mongoose service to fit your needs if you get stuck. Another option for the aggregate's would be to run the query yourself and set |
Keep in mind that Feathers services are not much more than normal Express middleware (except that you don't have to do the annoying request response handling). The pre-built adapters are just convenience wrappers for the 95% case, for more complex aggregates it often makes more sense to create a new custom service (although as @jamesjnadeau pointed out, it may also be possible with hooks). Your existing code can be pretty much 1 to 1 copied and turned into a service class: const { promisify } = require('utils');
class FindEvents {
async find(params) {
let q = params.query.query ? JSON.parse(params.query.query) : {};
let filterByLocation = false;
let andQuery = [];
let aggregationQueries = [];
const toMeters = (distanceInMile) => {
return distanceInMile * 1609.34; // return distance in meters
}
if (_.has(q, 'near') && q.near) {
filterByLocation = true;
let maxDistance = toMeters( +q.near.maxDistance || 10 );
let longitude = +q.near.loc[0] || -55.5806770;
let latitude = +q.near.loc[1] || 30.7211210;
let locationAggregation = { "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ longitude, latitude ]
},
"spherical": true,
"maxDistance": maxDistance,
"distanceField": "location.distance",
}};
aggregationQueries.push( locationAggregation );
}
if (_.has(q, 'text') && q.text) {
if ( !filterByLocation ) {
// if there is no location filter..
aggregationQueries.push({ $match: { $text: { $search: q.text }}}, {$sort: { score: { $meta: "textScore" }}});
} else {
// with location filter..
let keywords = q.text.split(" ");
let keyworkdsLen = keywords.length;
if (keyworkdsLen > 0){
let regexes = [];
for (var i = 0; i < keyworkdsLen; i++) {
regexes[i] = new RegExp(keywords[i], "i");
}
andQuery.push({ $or : [ { name: {$in: regexes} },
{ description: {$in: regexes} },
{ keywords: {$in: keywords} }]
});
}
}
}
if (_.has(q, 'category') && q.category) {
// Increment popularity.
let categories = q.category;
categories.forEach((category)=>{
Category.incrementPopularity(category);
});
andQuery.push({"category._id": { $in: categories }});
}
if (_.has(q, 'type') && q.type) {
andQuery.push({"type": { $in: q.type }});
}
if (_.has(q, 'status') && q.status) {
andQuery.push({"status": { $in: q.status }});
}
if (_.has(q, 'method') && q.method) {
andQuery.push({"method": { $in: q.method }});
}
if (andQuery.length > 0) {
// Filter events that are not public.
andQuery.push(publicEvents);
andQuery.push(nonDeletedEvents);
aggregationQueries.push({ "$match" : { "$and" : andQuery }});
// TODO: make sort dynamic
aggregationQueries.push({ "$sort" : { "dates.end_at": 1 }});
}
if ( aggregationQueries.length > 0 ) {
// Get the Mongoose model
const Event = this.app.service('events').Model;
return promisify(Event.aggregate(aggregationQueries).allowDiskUse(true).exec)();
} else {
return this.app.service('events').find({
query: publicEvents
});
}
}
setup(app) {
// Keep a reference to `app` so we can get the model
this.app = app;
}
} |
Hi @daffl ,
or we can do:
And in the mongoose service we will need to add an extra condition for ` } and this will use the following function from Mongoose: http://mongoosejs.com/docs/api.html#query_Query-nearSphere What do you think ? |
Hi @daffl I managed to do it with hooks |
I'm trying to convert some non-feathers mongoose code to feathers and it looks like there are ten ways to do it and I guess I'm not familiar enough with them to translate them to feathers. An example would be really helpful.
The text was updated successfully, but these errors were encountered: