我目前正在尝试按三个值的键排序和排序。但是让我们从文档结构开始:
{
_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);
}
在查询couchDB HTTP接口时,我尝试了像
这样的请求HTTP GET xxx/messages?key=[{}, "USERIDGOESHERE02", {}]
或
HTTP POST xxx/messages
{
keys: [
[{}, "USERIDGOESHERE02", "USERIDGOESHERE01"],
[{}, "USERIDGOESHERE02", "USERIDGOESHERE03"],
[{}, "USERIDGOESHERE02", "USERIDGOESHERE04"],
]
}
但所有这些都没有产生我想要制作的文件清单。你对这个任务有什么建议吗?或者用couchDB构建这样的过滤结果是不可能的? 非常感谢你提前!
答案 0 :(得分:6)
在一个长的1维列表中,键始终从最小到最高排序。 (我试图在The Parable of CouchDB中直观地描述这个,但不知道我是否成功了!)
数组从最小到最大的排序是什么样的?如果您读取视图中的所有键,则左侧值变化最小;中间值变化大于左边;而且右手价值变化最大。换句话说,数组键告诉CouchDB,“首要任务是按key[0]
排序,如果相等,则决胜局将是key[1]
;如果相等,那么下一个决胜局就是{ {1}}等......“
因此,您可能希望您的密钥看起来像这样:
key[2]
要从sender_B以及公共消息中查找receiver_1的所有消息,您需要两个查询,一个用于[ "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 ],
配对,另一个用于"receiver_1", null
。您想知道任何日期,因此您需要与发件人/收件人匹配的范围行。不幸的是,HTTP POST查询不支持此功能。
您可以简单地查询每个选定的发件人(甚至所有发件人同时使用线程或异步编程)。接收方和发送方是已知的,此示例允许从最小值("receiver_1", "sender_B"
)到最大值(null
)的范围,其中包括所有日期。
{}
另一种选择是简化您的密钥并删除日期。
?startkey=["receiver_1",null,null]&endkey=["receiver_1",null,{}]
?startkey=["receiver_1","sender_B",null]&endkey=["receiver_1","sender_B",{}]
现在您可以再次使用HTTP POST API进行查询。消息将按日期返回而不是。这不是很糟糕,您可以在客户端(或[ "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"],
函数)对它们进行排序。请记住,即使在我的第一个例子中,日期也没有完全排序。
答案 1 :(得分:5)
我想你想要;
emit([doc.author, doc.receiver[idx], doc.date], null);
然后您可以使用
进行查询startkey=["USERID1","USERID2"]&endkey=["USERID1","USERID2",{}]
这将按照日期顺序返回USERID1发送给USERID2的所有文档。 {}是一个空对象,根据CouchDB排序规则,排序将高于任何数字或字符串,因此这里的范围保证包括所有可能的日期。
最后,我会注意到CouchDB不支持通配符。