如何在Amplify GraphQL中按与已知位置的距离排序单杠数据?
按距离排序GraphQL返回的PullUpBar列表
当然可以实现按距离排序,分两种方案,优先推荐服务器端处理:
一、服务器端排序(最优选择)
如果数据量较大,客户端排序效率低,让后端直接返回排好序的结果是更合理的方式:
- 修改GraphQL查询:新增用户当前位置的参数,还可以让后端返回计算好的距离值(可选)
query PullUpBarsByDistance($userID: String, $currentLat: Float!, $currentLng: Float!) { PullUpBarsByDistance( type: "PullUpBar" currentLat: $currentLat currentLng: $currentLng sortDirection: ASC # 从近到远排序,用DESC则是从远到近 ) { items { id lat lng userID distance # 可选:后端返回已计算的距离,客户端无需重复计算 } } } - 后端实现逻辑:用你指定的欧几里得距离公式
d=√((x2 – x1)² + (y2 – y1)²)计算每个单杠到用户位置的距离,再按距离排序返回。比如用SQL数据库的话,可直接在查询中写计算逻辑:
(注:如果是真实地理场景,球面距离会更精准,但你指定了欧几里得距离,用这个逻辑即可)SELECT id, lat, lng, userID, SQRT(POW(lat - {currentLat}, 2) + POW(lng - {currentLng}, 2)) AS distance FROM pullup_bars WHERE type = 'PullUpBar' ORDER BY distance ASC;
二、客户端排序(后端无法修改时)
如果服务器端没法调整,就在客户端拿到数据后自行处理:
- 写一个计算距离的工具函数:
// 计算单杠到用户位置的欧几里得距离 function getDistance(userLat, userLng, bar) { const latDiff = bar.lat - userLat; const lngDiff = bar.lng - userLng; return Math.sqrt(Math.pow(latDiff, 2) + Math.pow(lngDiff, 2)); } - 对返回的列表进行排序:
// 假设userLat、userLng是用户当前经纬度,queryResult是GraphQL返回的结果 const sortedPullUpBars = queryResult.PullUpBarsByDate.items.sort((barA, barB) => { const distA = getDistance(userLat, userLng, barA); const distB = getDistance(userLat, userLng, barB); return distA - distB; // 从近到远排序,反转则是从远到近 });
内容的提问来源于stack exchange,提问作者Sebastian Meckovski
相关产品推荐
相关产品推荐

