To calculate the sum of distances, you can use the $geoNear aggregation pipeline operator in MongoDB, which allows you to calculate the distance between two points on a sphere using the Haversine formula. Here's an example query that sorts user lists based on their distance from a logged-in user and returns the sum of distances for each user:
db.users.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [longitude, latitude] },
distanceField: "distance",
spherical: true
}
},
{
$group: {
_id: "$_id",
username: { $first: "$username" },
distanceSum: { $sum: "$distance" }
}
},
{
$sort: { distanceSum: 1 }
}
])
This query first uses $geoNear to get the distance between the point specified by longitude and latitude and each user's coordinates. The distance is stored in the "distance" field for each document. It then groups the documents by the user's _id and username, and calculates the sum of distances for each user using $sum. Finally, it sorts the result by distanceSum in ascending order.
In Java Spring Boot, you can use the MongoTemplate class to execute this query. Here's an example method that returns a list of User objects sorted by their distance from a given point:
public List<User> getUsersSortedByDistance(double longitude, double latitude) {
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory);
Aggregation agg = Aggregation.newAggregation(
Aggregation.geoNear("users")
.near(new Point(longitude, latitude))
.distanceField("distance")
.spherical(true),
Aggregation.group("_id", "username")
.first("$_id").as("id")
.first("$username").as("username")
.sum("distance").as("distanceSum"),
Aggregation.sort(Sort.Direction.ASC, "distanceSum")
);
AggregationResults<BasicDBObject> results = mongoTemplate.aggregate(agg, "users", BasicDBObject.class);
List<User> users = new ArrayList<>();
for (BasicDBObject result : results) {
User user = new User();
user.setId(result.getInteger("id"));
user.setUsername(result.getString("username"));
user.setDistanceSum(result.getDouble("distanceSum"));
users.add(user);
}
return users;
}
This method uses the Aggregation class to define the aggregation pipeline and the MongoTemplate class to execute the query. It returns a list of User objects sorted by their distanceSum property. Note that you'll need to inject the MongoDbFactory instance into your Spring Boot application context in order to use the MongoTemplate class.
Please start posting anonymously - your entry will be published after you log in or create a new account. This space is reserved only for answers. If you would like to engage in a discussion, please instead post a comment under the question or an answer that you would like to discuss
Asked: 2021-12-05 11:00:00 +0000
Seen: 8 times
Last updated: Dec 04 '21
How can the rejection of the class text_plain from JavaMail API due to a VerifyError be confirmed?
What is the process for generating a dynamic subdomain/URL using vue.js?
How can the style of the loader be modified while the form submission is being processed?
I'm attempting to develop a Javascript-based comments section for my website.
What are some feasible methods to enable MIDI file playback on a web browser?
How can I resolve the issue of being unable to use Fetch to POST an array of Selected Checkboxes?
What is the method to hide the scroll button when reaching the bottom?
What is the process of using a custom nunjucks filter to filter collections in an eleventy template?