不知道这个问题听起来如何,但我想无论如何我都会抛出蝙蝠信号......我有一个类似于以下内容的数据集:
[
{ name: "Peter", score: 1000 },
{ name: "James", score: 800 },
{ name: "John", score: 600 },
{ name: "Saul", score: 400 },
{ name: "David", score: 200 }
]
现在我想对这个集合做一些事情,但我热衷的主要功能是获取给定的记录并找到位于分数表中该项目正上方和下方的文档,例如;
[
{ name: "James", score: 800 },
-> { name: "John", score: 600 },
{ name: "Saul", score: 400 }
]
我还想创建一个如下所示的视图:
[
{ key: 1, value: { name: "Peter", score: 1000 } },
{ key: 2, value: { name: "James", score: 800 } },
{ key: 3, value: { name: "John", score: 600 } },
{ key: 4, value: { name: "Saul", score: 400 } },
{ key: 5, value: { name: "David", score: 200 } }
]
我不禁觉得这两个问题是相关的。我也热衷于在尽可能少的 REST 请求中执行"采摘"......
我也很乐意接受依赖于应用程序层的解决方案,但同样,我想避免多次访问数据库,并且还希望避免提取不必要的数据。
有什么想法吗?
您可以创建将分数作为键的视图。map函数只需要做emit(doc.score, null)
,其中doc是传递给函数的文档。如果使用 startkey=600
、 limit=2
和 descending=false
查询此视图,则会得到分数为 600 和 800 的文档。如果您使用 startkey=600
、 limit=2
和 descending=true
进行查询,您将获得得分为 600 和 400 的文档。
要按降序分数顺序获取所有文档,您只需使用降序=true 进行查询,而不使用其他参数。当然,您不会获得key: n
字段,但您可以轻松地将其添加到应用程序层中。
您是否尝试过使用分数作为关键?在这种情况下,您可以构建评级图表并查询得分在某个范围内的人。您的地图功能:
function(doc){
emit(doc.score, {'name': doc.name, 'score': doc.score})
}
不确定你还需要这样的值
现在,如果您调用视图,您将收到:
{
"total_rows": 5, "offset": 0, "rows": [
{"id": "1", "key": 200, "value": {"name": "David", "score": 200}},
{"id": "2", "key": 400, "value": {"name": "Saul", "score": 400}},
{"id": "3", "key": 600, "value": {"name": "John", "score": 600}},
{"id": "4", "key": 800, "value": {"name": "James", "score": 800}},
{"id": "5", "key": 1000, "value": {"name": "Peter", "score": 1000}}
]
}
看起来不像最高评分。让我们添加descending=true
查询参数:
{"total_rows": 5, "offset": 0, "rows": [
{"id": "5", "key": 1000, "value": {"name": "Peter", "score": 1000}},
{"id": "4", "key": 800, "value": {"name": "James", "score": 800}},
{"id": "3", "key": 600, "value": {"name": "John", "score": 600}},
{"id": "2", "key": 400, "value": {"name": "Saul", "score": 400}},
{"id": "1", "key": 200, "value": {"name": "David", "score": 200}}
]}
好!现在,您可以应用startkey
/endkey
查询参数来查询指定范围内的事物。让我们拿startkey=799&endkey=401
.请注意,响应中包含边框值:
{"total_rows":5,"offset":2,"rows":[
{"id":"3","key":600,"value":{"name":"John","score":600}}
]}
结果查询将如下所示http://localhost:5984/db/_design/ddoc/_view/by_score?descending=true&startkey=799&endkey=401
我会创建一个数据集的轻量级视图(emit("score",null),正如 Kxepal 和 Kim 所建议的那样)将其拉出、缓存,并使用更改源来保持新鲜。
这样,我最终会减少对数据库的访问。这应该以某种方式使"采摘"过程更容易,因为我可以显式地将"rank"属性添加到缓存的对象属性/元素中,并使用它来挑选东西。
更新:
尽管上述方法可以作为解决方案(Redis的可能用例?),但使用视图响应total_rows和偏移量值使检索文档"排名"变得微不足道(基于"分数"视图,如上面的两个答案所示)...
唯一仍然存在的问题是"采摘"本身,它可能仍然需要两个单独的 API 调用,但这可能不是那么糟糕......
不过仍然愿意接受建议。
干杯。 :)