CouchDB通过三个索引键查询和过滤

sic*_*ics 3 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"
}
Run Code Online (Sandbox Code Playgroud)

主要目标是查询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);
}
Run Code Online (Sandbox Code Playgroud)

在查询couchDB HTTP接口时,我尝试了类似的请求

HTTP GET xxx/messages?key=[{}, "USERIDGOESHERE02", {}]
Run Code Online (Sandbox Code Playgroud)

要么

HTTP POST xxx/messages
{
    keys: [
        [{}, "USERIDGOESHERE02", "USERIDGOESHERE01"],
        [{}, "USERIDGOESHERE02", "USERIDGOESHERE03"],
        [{}, "USERIDGOESHERE02", "USERIDGOESHERE04"],
    ]
}
Run Code Online (Sandbox Code Playgroud)

但是所有这些都没有产生我想要制作的文件清单.你对这个任务有什么建议吗?或者用couchDB构建这样的过滤结果是不可能的?非常感谢你提前!

Jas*_*ith 7

在一个长的1维列表中,键总是从最小到最高排序.(我试图在CouchDB的寓言中直观地描述这个,但不知道我是否成功了!)

数组从最小到最大的排序是什么样的?如果您读取视图中的所有键,则左侧值变化最小; 中间值变化大于左边; 而且右手价值变化最大.换句话说,数组键告诉CouchDB,"第一优先级是排序key[0],如果相等,那么key[1]决胜局就是;如果那些也相等,那么下一个决胜局就是key[2]......"

因此,您可能希望您的键看起来像这样:

[ "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   ],
Run Code Online (Sandbox Code Playgroud)

要从sender_B以及公共消息中查找receiver_1的所有消息,您需要两个查询,一个用于"receiver_1", null配对,另一个用于"receiver_1", "sender_B".您想知道任何日期,因此您需要一系列与发送方/接收方匹配的行.不幸的是,HTTP POST查询不支持这一点.

您可以简单地查询每个选定的发送者(甚至所有发送者同时使用线程或异步编程).接收方和发送方是已知的,此示例允许从最小值(null)到最大值({})的范围,其中包括所有日期.

?startkey=["receiver_1",null,null]&endkey=["receiver_1",null,{}]
?startkey=["receiver_1","sender_B",null]&endkey=["receiver_1","sender_B",{}]
Run Code Online (Sandbox Code Playgroud)

另一种选择是简化您的密钥并删除日期.

[ "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"],
Run Code Online (Sandbox Code Playgroud)

现在,您可以再次使用HTTP POST API进行查询.邮件将按日期返回.这不是很糟糕,您可以在客户端(或_list函数)上对它们进行排序.请记住,即使在我的第一个例子中,日期也没有完美排序.


Rob*_*son 5

我想你想要;

emit([doc.author, doc.receiver[idx], doc.date], null);
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用查询

startkey=["USERID1","USERID2"]&endkey=["USERID1","USERID2",{}]
Run Code Online (Sandbox Code Playgroud)

这将按照日期顺序返回USERID1发送给USERID2的所有文档.{}是一个空对象,并且根据CouchDB排序规则,排序将高于任何数字或字符串,因此这里的范围保证包括所有可能的日期.

最后,我会注意到CouchDB不支持通配符.