我们可以在 CouchDB 中对排序列表视图进行排序吗?
Can we sort a sorted list view in CouchDb?
我有一个包含事件的开始时间和坐标的couchdb。我写了一个列表视图,用于计算从当前位置到这些事件的距离,如下所示:
locateEvents: function(head, req){
var row, comma = '';
start({
"headers": {
"Content-Type": "application/json"
}
});
if(req.query.latitude&&req.query.longitude&&req.query.radius&&req.query.now){
var R = 6371; // km
var dLon, dLat, lat1, lat2;
var results = [];
while(row = getRow()) {
dLon = Math.abs(row.value.venue.longitude-req.query.longitude);
dLat = Math.abs(row.value.venue.latitude-req.query.latitude);
dLon = (dLon*3.14159)/180;
dLat = (dLat*3.14159)/180;
lat1 = (Math.abs(req.query.longitude)*3.14159)/180;
lat2 = (Math.abs(req.query.latitude)*3.14159)/180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
if((d < req.query.radius)&&(row.value.start_time > req.query.now)){
results.push(row.value);
}
}
send(JSON.stringify(results));
}else{
start({"code": 500});
send("Latitude, longitude, page and radius parameters should be provided. i.e: latitude=value&longitude=value&radius=value&now=value");
}
我对事件有一个简单的按日期视图,如下所示:
byDate: {
map: function(doc){ if (doc.resource === 'Event') {emit(doc.venue.start_time, doc);}}
}
我的担忧:有没有办法先按列表中的距离对事件进行排序,然后按开始时间重新排序列表?
如果我理解正确,您希望最近的事件首先出现。如果同一距离内有两个事件,请先显示最早的事件。
这可以通过在将对象推送到结果集之前将计算的距离保存在对象中来完成:
row.value._distance = d;
results.push(row);
请注意,您现在无法保存文档,因为所有以下划线_
开头的字段都由 couchdb 保留。但是,由于每个请求到事件的距离可能不同,这很好。如果您需要将文档保存回存储,请记住删除该属性。
在下一步中,我们需要想出一种对事件进行排序的聪明方法 - 我们需要的所有信息现在都存储在文档中。
由于 JavaScript 不太喜欢对复杂的数据结构进行排序,因此我们必须做一些跑腿工作:
var sort = function(a,b) {
if (JSON.stringify(a) == JSON.stringify(b)) return 0;
return (JSON.stringify([a,b]) == JSON.stringify([a,b].sort())) ? -1 : 1
};
此函数只是对简单值的数组进行排序,如下所示:
> sort(["a",1], ["a", 0])
1
> sort(["a",0], ["a", 1])
-1
> sort(["a",0], ["a", 0])
0
现在是有趣的部分,在将结果send
回客户端之前,请对它们进行排序:
// ...
results.sort(function(a, b) {
return sort(
[a.value._distance, a.value.venue.start_time],
[b.value._distance, b.value.venue.start_time]
);
});
send(JSON.stringify(results));
例:
[{"value": {"_distance": 100, "venue": { "start_time": "Wed, 21 Mar 2012 04:31:24 -0700" } } },
{"value": {"_distance": 212, "venue": { "start_time": "Sat, 13 Oct 2012 02:52:12 -0700" } } },
{"value": {"_distance": 235, "venue": { "start_time": "Mon, 22 Jul 2013 12:50:20 -0700" } } },
{"value": {"_distance": 677, "venue": { "start_time": "Thu, 09 May 2013 03:39:55 -0700" } } },
{"value": {"_distance": 654, "venue": { "start_time": "Thu, 29 Sep 2011 15:31:46 -0700" } } },
{"value": {"_distance": 100, "venue": { "start_time": "Tue, 20 Sep 2011 19:16:37 -0700" } } }]
使用上面的sort
函数后变为:
[{"value": {"_distance": 100, "venue": {"start_time": "Tue, 20 Sep 2011 19:16:37 -0700" } } },
{"value": {"_distance": 100, "venue": {"start_time": "Wed, 21 Mar 2012 04:31:24 -0700" } } },
{"value": {"_distance": 212, "venue": {"start_time": "Sat, 13 Oct 2012 02:52:12 -0700" } } },
{"value": {"_distance": 235, "venue": {"start_time": "Mon, 22 Jul 2013 12:50:20 -0700" } } },
{"value": {"_distance": 654, "venue": {"start_time": "Thu, 29 Sep 2011 15:31:46 -0700" } } },
{"value": {"_distance": 677, "venue": {"start_time": "Thu, 09 May 2013 03:39:55 -0700" } } }]
请注意,排序后,前两个对象具有_distance == 100
但由于第一个对象较早,因此首先排序。
希望对您有所帮助!
相关文章:
- 我们可以在 CouchDB 中对排序列表视图进行排序吗?
- 表排序器寻呼机在调查视图上不起作用
- 在不涉及控制器的情况下对MVC视图列表中的项进行排序
- (钛工作室)显示带有排序数据的表视图
- 等优先级视图排序规则 CouchDB
- AngularJS - 在服务内部对数组进行排序,在控制器/视图中保留绑定
- 如何在WinJS中为列表视图创建排序功能
- CouchDB 中的筛选和排序视图
- 当我使用视图而不是使用Famous的表面进行排序时,ScrollViewContainer不会滚动
- 如何使用布局管理器重新排序/排序嵌套视图而不重新渲染
- 如何在列表视图中使用
类对项目进行排序 - 在backbone.js中,如何使用新的模型数据更新视图,同时在没有完整渲染的情况下保持排序顺序
- 如何在不点击标题的情况下从客户端对网格视图进行排序
- 如何使用函数对Google Charts数据表或数据视图进行排序
- 让backbone.js视图知道jQuery排序表中的更新
- 骨干排序只适用于视图
- 非排序列表视图(插入时显示)
- Mithril.js:如果视图使用子组件,排序数据不会重新渲染
- 未捕获的JS错误在Extbase扩展排序记录在列表视图
- CouchDB / Couchbase视图按键数排序