有没有办法在CouchDB中执行以下操作?一种通过给定键返回唯一,不同值的方法吗?
SELECT DISTINCT field FROM table WHERE key="key1"
'key1' => 'somevalue'
'key1' => 'somevalue'
'key2' => 'anotherval'
'key2' => 'andanother'
'key2' => 'andanother'
例如:
http://localhost:5984/database/_design/designdoc/_view/distinctview?key=“key1”将返回['somevalue']
http://localhost:5984/database/_design/designdoc/_view/distinctview?key=“key2”将返回['anotherval','andanother']
答案 0 :(得分:9)
As suggested in the CouchDB definitive guide,您应该在密钥中放置您想要唯一的值,然后使用group=true
查询reduce函数。
例如,假设keyfield
是包含“key1”和“key2”的字段,而valuefield
是包含值的字段,则您的地图功能可以是:
function(doc) {
// filter to get only the interesting documents: change as needed
if (doc.keyfield && doc.valuefield) {
/*
* This is the important stuff:
*
* - by putting both, the key and the value, in the emitted key,
* you can filter out duplicates
* (simply group the results on the full key);
*
* - as a bonus, by emitting 1 as the value, you get the number
* of duplicates by using the `_sum` reduce function.
*/
emit([doc.keyfield, doc.valuefield], 1);
}
}
你的reduce函数可以是:
_sum
然后使用group=true&startkey=["key2"]&endkey=["key2",{}]
查询:
{"rows":[
{"key":["key2","anotherval"],"value":1},
{"key":["key2","andanother"],"value":2}
]}
答案 1 :(得分:3)
根据我在此处看到的内容,(我会在需要时更改我的答案)key1
和key2
看起来像独立字段,因此您需要2个单独的视图。
我在测试数据库中创建了5个简单文档:
// I've left out fields like _id and _rev for the sake of simplicity
{ "key1": "somevalue" }
{ "key1": "somevalue" }
{ "key2": "anotherval" }
{ "key2": "andanother" }
{ "key2": "andanother" }
以下是您需要的2个视图查询:
// view for key1
function(doc) {
if (doc.key1) {
emit("key1", doc.key1);
}
}
// view for key2
function(doc) {
if (doc.key2) {
emit("key2", doc.key2);
}
}
从那里,你的reduce函数可以通过这样做返回数组中的所有值:
function (key, values) {
return values;
}
但是,您特别提到了不同值。由于JavaScript没有数组的本地unique()
方法,并且我们不能在视图函数中使用CommonJS模块,因此我们必须为此添加自己的逻辑。我只是复制粘贴了我在Google上找到的第一个array.unique()
函数,您可以编写自己的函数,以便更好地进行优化。
function (key, values, rereduce) {
var o = {}, i, l = values.length, r = [];
for (i = 0; i < l; i += 1) {
o[values[i]] = values[i];
}
for (i in o) {
r.push(o[i]);
}
return r;
}
您将在两个视图中使用相同的reduce函数。查询任何这些视图时,默认情况下它也会执行reduce。 (您需要明确传递reduce=false
以获取map
函数的结果。
以下是您使用上述map/reduce
查询检索的结果集:(请记住它们是2个单独的查询)
{"rows":[
{"key":"key1", "value": ["somevalue"]}
]}
{"rows":[
{"key": "key2", "value": ["anotherval", "andanother"]}
]}