bounty还有15小时到期,回答此问题可获得+150声望奖励,The Old County正在寻找规范答案:我正在使用getUserList API --并且我已经获得了当前功能来对集合中的普通字段进行排序--但是我希望能够使用登录用户的纬度/lng作为基础通过距离进行排序--以计算与其他用户的纬度/lng的距离---请查看简报的顶部,其中我列出了“@GetMapping”的当前控制器(“/API/users”)”
在switch的例子中,我希望能够通过距离对用户进行排序,我认为这意味着使用聚合来创建虚拟距离字段,我不确定如何集成它,我只知道一些制作聚合的方法,但是没有任何东西可以使用addCriteria Springboot方法添加到我的代码库中。
我正在一个Java/Mongodb系统上工作,在这个系统中,每个用户都有自己的lat/lng坐标
我已经对用户集合进行了一个API查询--我想开始对用户进行过滤/排序。
我想完成这个排序过程--它对选项2-5很好--但是我需要弄清楚如何在mongo中创建一个聚合(我是新手)。
一个用户记录看起来像这样--我把坐标放在locations对象中,其他过滤器大多在根目录中--比如createdAt,lastLoginAt...
如何开始使用当前代码库创建所需的聚合--这样我就可以对登录的用户进行排序--获取他们的坐标--并对查看列表中的用户进行排序。
使用springframework导入
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
@CrossOrigin
@GetMapping("/api/users")
@ResponseBody
public BasicDBObject listUsers (@RequestHeader("Authorization") String bearerToken, @RequestParam("sort_by") String sort_by, @RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "3") int size) {
String email = tokenHandler.getEmailFromBearerToken(bearerToken);
//get logged in user
Query q = new Query();
q.addCriteria(Criteria.where("email").is(email));
List<Person> lp = MongoApp.mongoOps().find(q, Person.class);
Person loggedInUser = null;
if (!lp.isEmpty()) {
for (Person person : lp) {
loggedInUser = person;
}
}
String field = "";//createdAt
switch (sort_by) {
case "1":
System.out.println("Distance");
break;
case "2":
System.out.println("Last online");
field = "lastLoginAt";
break;
case "3":
System.out.println("Latest joined");
field = "createdAt";
break;
case "4":
System.out.println("Newest photo");
field = "newestImageAt";
break;
case "5":
System.out.println("Recently Updated");
field = "updatedAt";
break;
default:
System.out.println("default");
field = "createdAt";
}
Query query = new Query();
long totalUsercount = MongoApp.mongoOps().count(query, Person.class);
//only show isActive users
query.addCriteria(Criteria.where("isActive").is(true));
//dont show yourself - loggedin user excluded from list
query.addCriteria(Criteria.where("id").ne(loggedInUser.getId()));
query.with(Sort.by(Sort.Direction.DESC, field));
Pageable pageable = PageRequest.of(page, size);
List<Person> totalPeople = new ArrayList<>();
totalPeople = queryPeopleAddImages(totalPeople, query);
long totalCount = totalPeople.size();
query.with(pageable);
// List People
List<Person> people = new ArrayList<>();
people = queryPeopleAddImages(people, query);
BasicDBObject obj = userListResponse(loggedInUser, people, totalCount, totalUsercount);
return obj;
}
我在这里添加了一些研究链接-我认为这些链接正在逐步完善这个功能
研究
How to write MongoDb Aggregation for this Criteria query
AggregationOperation match = Aggregation.match(Criteria.where("careGiverId").is(careTakerId).and("careType").is(careType));
AggregationOperation count = Aggregation.count().as("count");
Aggregation agg = Aggregation.newAggregation(match, count);
mongoOperations.aggregate(agg, CareLogBean.class);
AggregationOperation match = Aggregation.match(matching criteria);
AggregationOperation group = Aggregation.group("fieldname");
AggregationOperation sort = Aggregation.sort(Sort.Direction.ASC, "fieldname");
Aggregation aggregation = Aggregation.newAggregation(Aggregation.unwind("fieldname"),match,group,sort);
MongoDB print distance between two points
db.new_stores.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ -81.093699, 32.074673 ]
},
"maxDistance": 500 * 1609,
"key" : "myLocation",
"spherical": true,
"distanceField": "distance",
"distanceMultiplier": 0.000621371
}}
]).pretty()
“这允许您指定“distanceField”,它将在输出文档中生成另一个字段,其中包含与查询点的距离。您还可以使用“distanceMultiplier”根据需要对输出距离应用任何转换(即米到英里,并注意所有GeoJSON距离都以米为单位返回)
还有一个具有类似选项的geoNear命令,但它当然不会返回光标作为输出。
如果有多个2dsphere,则应指定“键”。
我有这个工作在前端计算距离公里
计算两个经纬度点之间的距离?(半正矢公式)
用半正矢公式
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}
2023年3月28日当前研究
我正在开发一个mongobdb应用程序-使用Java springboot。
它是一个用户网站--成员将登录并能够搜索/过滤/排序其他成员。
我已经开始构建一个带有基本查询的API--
我需要完成API的一部分,以允许您通过距离进行排序。每个用户都有lat/lng详细信息--我相信这是构建聚合查询的一个案例。
使用mongodb/java springboot通过登录用户和用户列表之间的距离进行排序的查询中的距离增加
- 处理距离排序--聚合查询部分。
- 我想清理代码库-因为有单独的api做类似/相同的搜索,但特定的过滤器- getUsers,getFavs,getBlocks,getViewedMe -
- 也使分页选项可选-(或在其自己的函数中有一部分代码,以隔离它与可选的分页处理-又名减少重复的代码工作)-所以我可以获取所有用户数据,而不是它的块进行分析-再次类似的搜索/相同但可扩展-又名只提供5个最新的结果,提供分页数据与排序/过滤。
- 能够添加多种类型的过滤器-与或操作-图像只,金发,蓝眼睛,种族
--所以你可以在这里看到--其他情况也可以--因为它们是实际的字段--- lastLoginAt,createdAt ----等等--而distance就像是一个需要创建的虚拟字段--我认为使用聚合
String field = "";//createdAt
switch (sort_by) {
case "1":
System.out.println("Distance");
break;
case "2":
System.out.println("Last online");
field = "lastLoginAt";
break;
case "3":
System.out.println("Latest joined");
field = "createdAt";
break;
case "4":
System.out.println("Newest photo");
field = "newestImageAt";
break;
case "5":
System.out.println("Recently Updated");
field = "updatedAt";
break;
default:
System.out.println("default");
field = "createdAt";
}
Query query = new Query();
long totalUsercount = MongoApp.mongoOps().count(query, Person.class);
System.out.println("totalUsercount "+ totalUsercount);
///default filters (only active users, no admins, no self)
query = addDefaultFilters(query, loggedInUser);
///default filters
//country filter
//query.addCriteria(Criteria.where("country").is("AR"));
query.with(Sort.by(Sort.Direction.DESC, field));
“MongoDB Compass终端,非常适合测试查询和聚合”
在这里添加了mongodb中的索引和2dsphere索引类型的文档。
2dshpere:https://www.mongodb.com/docs/manual/core/2dsphere/#:~:text= A%202dsphere%20index%20supports%20queries,geospatial%20queries%2C%20see%20Geospatial%20查询。索引:https://www.mongodb.com/docs/manual/indexes/
MongoDB的$geoNear聚合阶段需要2dsphere索引才能正确处理地理空间数据。这是因为$geoNear使用2dsphere索引来高效地执行地理空间查询
已经有一个默认的过滤器
public Query addDefaultFilters(Query query, Person loggedInUser) {
///default filters
//only show isActive users
query.addCriteria(Criteria.where("isActive").is(true));
//dont show admins
query.addCriteria(Criteria.where("role").ne("ROLE_ADMIN"));
//dont show yourself - loggedin user excluded from list
query.addCriteria(Criteria.where("id").ne(loggedInUser.getId()));
///default filters
return query;
}
--
Query query = new Query();
long totalUsercount = MongoApp.mongoOps().count(query, Person.class);
System.out.println("totalUsercount "+ totalUsercount);
///default filters (only active users, no admins, no self)
query = addDefaultFilters(query, loggedInUser);
///default filters
//country filter
//query.addCriteria(Criteria.where("country").is("AR"));
query.with(Sort.by(Sort.Direction.DESC, field));
Pageable pageable = PageRequest.of(page, size);
List totalPeople = new ArrayList();
totalPeople = queryPeopleAddImages(totalPeople, query);
long totalCount = totalPeople.size();
System.out.println("xxxxxxxxxxxxxtotalCount "+totalCount);
query.with(pageable);
// List People
//List people = MongoApp.mongoOps().findAll(Person.class);
List people = new ArrayList();
people = queryPeopleAddImages(people, query);
另一个java示例
x 1c 12d1x
1条答案
按热度按时间3okqufwl1#
我使用过MongoDB,而不是springboot,但据我所知,你的问题是你想在不同字段的聚合中进行排序/过滤。对吗?
对于排序,您可以用途:
下面是用于排序的引用link。