Database CouchDB-“;采摘;视图中的最近邻文档。

Database CouchDB-“;采摘;视图中的最近邻文档。,database,oop,mapreduce,couchdb,Database,Oop,Mapreduce,Couchdb,不知道这个问题听起来会怎样,但我想我还是会扔掉蝙蝠信号。。。 我有一个类似于以下内容的数据集: [ { name: "Peter", score: 1000 }, { name: "James", score: 800 }, { name: "John", score: 600 }, { name: "Saul", score: 400 }, { name: "David", score: 200 } ] 现在,我想用这个集合做一些事情,但我喜欢的主要功

不知道这个问题听起来会怎样,但我想我还是会扔掉蝙蝠信号。。。 我有一个类似于以下内容的数据集:

[
    { 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 } }
]
我忍不住觉得这两个问题是相关的。 我也渴望在尽可能少的休息请求中执行“拉”操作

我也很乐意接受一个依赖于应用层的解决方案,但我还是希望避免多次访问数据库,也希望避免提取过多的数据


有什么想法吗?

您可以创建一个以分数为键的视图。map函数只需要执行
emit(doc.score,null)
,其中doc是传递给函数的文档。如果使用
startkey=600
limit=2
descending=false
查询此视图,您将得到分数为600和800的文档。如果您使用
startkey=600
limit=2
descending=true
进行查询,您将得到分数为600和400的文档


要以降序得分顺序获取所有文档,只需使用descending=true进行查询,而不需要其他参数。当然,您不会得到
key:n
字段,但您可以轻松地将其添加到应用程序层。

您是否尝试使用score作为键?在这种情况下,您可以为得分在一定范围内的人员构建评级图表和查询。您的地图功能:

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

我想我会创建一个数据集的轻量级视图(根据Kxepal和Kim的建议,emit(“score”,null))将其拉出,缓存,并使用更改提要保持其新鲜

那样的话,我对数据库的访问就会减少。这将使“提取”过程在某种程度上变得更容易,因为我可以显式地向缓存的对象属性/元素添加一个“rank”属性,并使用它来挑选东西

更新:

尽管上述方法可以作为一种解决方案(Redis的一个可能用例?),但使用视图响应合计行和偏移量值使得检索文档“排名”变得微不足道(基于“分数”视图,如上面两个答案所示)

唯一仍然存在的问题是“pull”本身,它可能仍然需要两个单独的API调用,但这可能不是那么糟糕

尽管如此,我仍然愿意接受建议


干杯。:)

这就是我目前考虑的解决方案。我喜欢“key:n”,因为我想避免为了找出“Peter”在表中的位置而不得不拿出1000行(或其他任何行)的结果集。我想做的另一件事是,按ID取出一个文档,并确定它的排名(可能还包括抽取邻居),而不必返回数据库并查询score属性。所以我想总结一下这一切有多复杂。。。这合理吗?在一般情况下,您必须在应用程序层计算您的
,尤其是当您试图建立实时评级列表时。原因很简单:视图是仅对更改的文档进行增量更新的。如果您添加分数为1200的Mike,您的视图将仅更新此文档,但其他文档保持不变。这可能会产生令人尴尬的结果。@Charlie:您可以使用视图顶部的列表函数来获取key:n。如果我选择按名称选择文档,那么我将如何检索秩/key:n?我每次都必须调用list函数吗?我当然想把整个模型保存在CouchDB中,但我正在努力解决这个问题。因此,问题就来了。再看一下这个问题,找到了一个依赖于CouchDB的total_行和offset值的解决方案。这两个属性都可以在每个成功的视图请求响应对象中找到。使用它们可以避免创建“key=n”。