Json 基于三个索引键的CouchDB查询和过滤
我目前正在尝试按一个包含三个值的键进行排序。但让我们从文档结构开始:Json 基于三个索引键的CouchDB查询和过滤,json,couchdb,mapreduce,Json,Couchdb,Mapreduce,我目前正在尝试按一个包含三个值的键进行排序。但让我们从文档结构开始: { _id: "DOCIDGOESHERE01", type: "MESSAGE", date: "2011-08-24 06:49:02", author: "USERIDGOESHERE01", receiver: ["USERIDGOESHERE02", "USERIDGOESHERE03"], message: "ok let's do this" } 主要目标是查询c
{
_id: "DOCIDGOESHERE01",
type: "MESSAGE",
date: "2011-08-24 06:49:02",
author: "USERIDGOESHERE01",
receiver: ["USERIDGOESHERE02", "USERIDGOESHERE03"],
message: "ok let's do this"
}
主要目标是查询couchDB,查找由选定用户发送给特定用户的消息,并按日期排序。有些消息没有任何接收者表明它们是公开的,任何人都可以阅读
我当前使用的映射函数如下所示:
function map(doc) {
if(doc.receiver.lenth==0)
emit([doc.date, null, doc.author], doc._id);
else for(var idx in doc.receiver)
emit([doc.date, doc.receiver[idx], doc.author], doc._id);
}
[ "receiver_1", null , a_date ],
[ "receiver_1", "sender_A", some_date ],
[ "receiver_1", "sender_B", another_date ],
[ "receiver_2", "sender_A", fourth_date ],
[ "receiver_3", "sender_C", fifth_date ],
当查询couchDB HTTP接口时,我尝试了如下请求
HTTP GET xxx/messages?key=[{}, "USERIDGOESHERE02", {}]
或
但所有这些都没有形成我想要制作的文件清单。你对这项任务有什么建议吗?或者用couchDB构建这样的过滤结果是不可能的?
提前非常感谢 在一个长的一维列表中,键总是从最小到最高排序。(我试图在中直观地描述这一点,但不知道我是否成功!) 从最小到最大排序的数组是什么样子的?如果读取视图中的所有关键点,左侧值变化最小;中间值的变化大于左侧值;右边的值变化最大。换句话说,数组键告诉CouchDB,“第一优先级是按
键[0]
排序,如果相等,则断开连接的键将是键[1]
;如果这些键也相等,则下一个断开连接的键将是键[2]
,以此类推。”
因此,您可能希望您的密钥如下所示:
function map(doc) {
if(doc.receiver.lenth==0)
emit([doc.date, null, doc.author], doc._id);
else for(var idx in doc.receiver)
emit([doc.date, doc.receiver[idx], doc.author], doc._id);
}
[ "receiver_1", null , a_date ],
[ "receiver_1", "sender_A", some_date ],
[ "receiver_1", "sender_B", another_date ],
[ "receiver_2", "sender_A", fourth_date ],
[ "receiver_3", "sender_C", fifth_date ],
要从发送方_B查找接收方_1的所有消息以及公共消息,您需要两个查询,一个查询“接收方_1”,null
配对,另一个查询“接收方_1”,“发送方_B”
。您想知道任何日期,因此需要一系列与发送方/接收方匹配的行。不幸的是,HTTP POST查询不支持这一点
您可以简单地查询每个选定的发送者(甚至使用线程或异步编程同时查询所有发送者)。接收方和发送方是已知的,此示例允许从最小值(null
)到最大值({}
)的范围,其中包括所有日期
?startkey=["receiver_1",null,null]&endkey=["receiver_1",null,{}]
?startkey=["receiver_1","sender_B",null]&endkey=["receiver_1","sender_B",{}]
[ "receiver_1", null ],
[ "receiver_1", "sender_A"],
[ "receiver_1", "sender_B"],
[ "receiver_2", "sender_A"],
[ "receiver_3", "sender_C"],
[ "receiver_3", "sender_C"],
[ "receiver_3", "sender_C"],
[ "receiver_3", "sender_C"],
[ "receiver_3", "sender_C"],
另一个选择是简化密钥并删除日期
?startkey=["receiver_1",null,null]&endkey=["receiver_1",null,{}]
?startkey=["receiver_1","sender_B",null]&endkey=["receiver_1","sender_B",{}]
[ "receiver_1", null ],
[ "receiver_1", "sender_A"],
[ "receiver_1", "sender_B"],
[ "receiver_2", "sender_A"],
[ "receiver_3", "sender_C"],
[ "receiver_3", "sender_C"],
[ "receiver_3", "sender_C"],
[ "receiver_3", "sender_C"],
[ "receiver_3", "sender_C"],
现在,您可以再次使用HTTP POST API进行查询。邮件将返回,不按日期排序。这还不错,您可以在客户端对它们进行排序(或使用\u列表
函数)。请记住,即使在我的第一个例子中,日期也不是完全排序的。我想你想要
emit([doc.author, doc.receiver[idx], doc.date], null);
然后,您可以使用
startkey=["USERID1","USERID2"]&endkey=["USERID1","USERID2",{}]
这将按日期顺序返回USERID1发送给USERID2的所有文档。{}是一个空对象,根据CouchDB排序规则,排序将高于任何数字或字符串,因此这里的范围保证包括所有可能的日期
最后,我要指出CouchDB不支持通配符。谢谢你的回复,我第一件意识到CouchDB是新来的,正如@user787145所说的,没有任何通配符。我学到的另一件事是,视图可以从一个起始索引读取到给定的结束索引,而无需在创建视图后从列表中过滤出一些文档。这就得出结论,视图本身必须包含过滤特征。无论如何,您的第三种方法似乎最适合我的用例。谢谢您的回复!因为@JasonSmith的回复更为详细,我决定将他的回答标记为回应——但我也喜欢你的回答!