在CouchDB中按键返回唯一值

6qqygrtg  于 2023-08-01  发布在  CouchDB
关注(0)|答案(3)|浏览(224)

在CouchDB中是否有以下操作?一种通过给定键返回唯一的、不同的值的方法?

  1. SELECT DISTINCT field FROM table WHERE key="key1"
  2. 'key1' => 'somevalue'
  3. 'key1' => 'somevalue'
  4. 'key2' => 'anotherval'
  5. 'key2' => 'andanother'
  6. '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']

f0ofjuux

f0ofjuux1#

正如CouchDB权威指南中所建议的,您应该将希望唯一的值放在键中,然后使用group=true查询reduce函数。
例如,假设keyfield是具有“key1”和“key2”的字段,valuefield是具有值的字段,则map函数可以是:

  1. function(doc) {
  2. // filter to get only the interesting documents: change as needed
  3. if (doc.keyfield && doc.valuefield) {
  4. /*
  5. * This is the important stuff:
  6. *
  7. * - by putting both, the key and the value, in the emitted key,
  8. * you can filter out duplicates
  9. * (simply group the results on the full key);
  10. *
  11. * - as a bonus, by emitting 1 as the value, you get the number
  12. * of duplicates by using the `_sum` reduce function.
  13. */
  14. emit([doc.keyfield, doc.valuefield], 1);
  15. }
  16. }

字符串
你的reduce函数可以是:

  1. _sum


然后用group=true&startkey=["key2"]&endkey=["key2",{}]查询得到:

  1. {"rows":[
  2. {"key":["key2","anotherval"],"value":1},
  3. {"key":["key2","andanother"],"value":2}
  4. ]}

展开查看全部
jogvjijk

jogvjijk2#

根据我在这里看到的,(如果需要,我会改变我的答案)key1key2看起来像独立的字段,所以你需要两个单独的视图。
我在我的测试数据库中创建了5个简单的文档:

  1. // I've left out fields like _id and _rev for the sake of simplicity
  2. { "key1": "somevalue" }
  3. { "key1": "somevalue" }
  4. { "key2": "anotherval" }
  5. { "key2": "andanother" }
  6. { "key2": "andanother" }

字符串
以下是您需要的2个视图查询:

  1. // view for key1
  2. function(doc) {
  3. if (doc.key1) {
  4. emit("key1", doc.key1);
  5. }
  6. }
  7. // view for key2
  8. function(doc) {
  9. if (doc.key2) {
  10. emit("key2", doc.key2);
  11. }
  12. }


从那里,你的reduce函数可以返回数组中的所有值,只需这样做:

  1. function (key, values) {
  2. return values;
  3. }


但是,您特别提到了distinct值。由于JavaScript没有原生的unique()数组方法,并且我们不能在视图函数中使用CommonJS模块,因此我们必须为此添加自己的逻辑。我只是复制粘贴了我在Google上找到的第一个array.unique()函数,你可以自己写一个更好的优化函数。

  1. function (key, values, rereduce) {
  2. var o = {}, i, l = values.length, r = [];
  3. for (i = 0; i < l; i += 1) {
  4. o[values[i]] = values[i];
  5. }
  6. for (i in o) {
  7. r.push(o[i]);
  8. }
  9. return r;
  10. }


您将在两个视图中使用相同的reduce函数。当你查询这些视图中的任何一个时,默认情况下它也会执行reduce。(您需要显式传递reduce=false以仅获取map函数的结果。
下面是使用上面的map/reduce查询检索的结果集:(请记住,它们是两个独立的查询)

  1. {"rows":[
  2. {"key":"key1", "value": ["somevalue"]}
  3. ]}
  4. {"rows":[
  5. {"key": "key2", "value": ["anotherval", "andanother"]}
  6. ]}

展开查看全部
vsmadaxz

vsmadaxz3#

  1. map: (doc, emit) => {
  2. emit(doc.tag, doc.value);
  3. },
  4. reduce: (keys, values, rereduce) => {
  5. if (rereduce) {
  6. let res = {};
  7. values.forEach(v => {
  8. res = {
  9. ...res,
  10. ...v
  11. }
  12. })
  13. }
  14. else {
  15. const res = {};
  16. keys.forEach((key, idx) => res[key[0] + ':' + values[idx]] = true);
  17. return res;
  18. }
  19. }

字符串
得到以下结果:

  1. key1:somevalue: true
  2. key2:andanother: true
  3. key2:anotherval: true


可以直接提取。

展开查看全部

相关问题