View 使用多个键查询视图

View 使用多个键查询视图,view,couchbase,View,Couchbase,给出gamesim示例的以下视图: function (doc, meta) { if (doc.jsonType == "player" && doc.experience) { emit([doc.experience,meta.id], doc.id); } } 我想为只属于特定组的用户查询排行榜分组数据在外部系统中维护 例如,如果视图中有橙色、紫色、绿色、蓝色和红色的用户,我希望排行榜只给出橙色和紫色的排名,而不必查询他们各自的当前体验点

给出gamesim示例的以下视图:

function (doc, meta) {
    if (doc.jsonType == "player" && doc.experience) {
       emit([doc.experience,meta.id], doc.id);
    }
}
我想为只属于特定组的用户查询排行榜分组数据在外部系统中维护

例如,如果视图中有橙色、紫色、绿色、蓝色和红色的用户,我希望排行榜只给出橙色和紫色的排名,而不必查询他们各自的当前体验点

...view/leaderboard?keys=[[null,"orange"],[null,"purple"]
下面的操作很好,但是需要额外的查询来预先找到橙色和紫色的体验点。然而,由于明显的原因,这并不具有规模

...view/leaderboard?keys=[[1,"orange"],[5,"purple"]
提前谢谢

一些NoSql与SQL背景 首先,您必须记住,特别是Couchbase的优势在于超快速存储和检索记录。标记是后来添加的,作为一种使存储更有用、更不容易出错的方法,请将它们更多地视为一种自动化的库存,它们的设计实际上限制了您摆脱SQL风格的思维方式。您上面的查询就是一个完美的例子:

select * 
from leaderboard 
where id in ('orange','purple')
order by experience
这是一个集检索、计算和过滤于一体的功能。这正是NoSql数据库优化所不做的,相反,SQL数据库是,这常常使它们变得极其复杂,但这是另一个主题

因此,这导致了SQL与NoSQL数据库之间的主要区别:NoSQL针对存储进行了优化,而SQL针对查询进行了优化。同时,它会导致人们调整对数据库角色的看法,在我看来,这应该是前者多于后者

Couchbase的创建者最初只关注数据库的存储方面。然而,当你知道你存储的是什么时,存储就变得更有意义了,索引是后来添加的一项功能,最初你必须跟踪你自己的东西——这并没有多大乐趣!他们还以一种利用CB同时存储和检索大量记录的能力的方式添加了MapReduce。这两个特性都不是为了解决复杂的查询问题,尽管这个查询很简单,但正因为如此,它才是一个完美的例子。这是应用程序逻辑的功能

解决您的具体问题 那么,现在谈谈你的问题。查询本身看起来很简单,事实上确实如此。但是,

select * from leaderboard
这其实并不简单。它是一个两层的深度查询,因为你对排行榜的定义意味着从最大到最小的玩家体验排序列表。因此,此查询扩展为:

select * from players order by experience desc
Couchbase在索引机制中本机支持上述功能记住,它对对象进行了编目,并且您在问题中准确地描述了如何利用视图来实现此输出。Couchbase不支持的是表示where子句的第三级查询。通常,在视图地图定义或索引选择参数中执行where in Couchbase。您不能在map中执行此操作,因为您并不总是想要相同的选择,也不能在index selection参数中执行此操作,因为索引是根据经验级别首先排序的

方法1 假设您正在网页上向用户显示此信息。通过按原样提取数据并抛出不需要的值,可以在客户端或web服务中轻松实现此过滤器。当用户向下滚动或单击更多页面时,使用“限制”和“跳过”参数可以请求更多内容,或者其他任何内容

方法2 颠倒索引的顺序,先按组或颜色排序,然后按经验等级排序。运行单独的查询以选择每种颜色的前“N”个用户,然后在客户端进行合并和排序。这将需要更长的时间来预先加载,但如果您出于这个原因需要它,它将为您提供一个更大的内存数据集。如果类别分布非常不均匀,则此方法可能无法正常工作,在这种情况下,需要调整“N”以匹配类别内的统计分布

要旨
其中一个想法是NoSql数据库设计用于处理高度动态的数据集。这需要一些统计思维,因为不再有一个单一的正确答案。在现实世界中总是会出现一定程度的不一致性和错误。您不能期望NoSql数据库返回完美的查询结果,因为没有完美。你必须满足于足够好——这通常比需要的要好得多。

为什么不简单地颠倒你的键数组的顺序呢?另外,发送文档Id是多余的。最好发送null。我需要使用经验对结果进行排序以获得排名。我看不出在键中颠倒顺序会如何产生解决方案。你是对的,发出文档Id是多余的,这只是我正在处理的一个示例。我想我不理解这个问题。索引按第一个el排序
元素,然后是第二个元素,依此类推。您能给出一个更清晰的输出示例吗?我希望输出按第一个元素doc.experience排序,并按第二个元素doc.id进行过滤:{total_rows:2,rows:[{id:orange,key:[1,orange],value:null},{id:purple,key:[5,purple],value:null}]你能写出等价的SQL查询吗?嗨!谢谢你的深入回答。我在设计项目时会考虑这些要点。