视图是设计文档的一部分。

视图函数

map函数

Map方法的参数只有一个,就是当前的文档对象。Map方法的实现需要根据文档对象的内容,确定是否要输出结果。 如果需要输出的话,可以通过emit来完成。 emit方法有两个参数,分别是key和value,分别表示输出结果的键和值。 使用什么样的键和值应该根据视图的实际需要来确定。 emit函数可以在map函数里被调用多次,创建一个文档的多个记录。 
当希望对文档的某个字段进行排序和过滤操作的时候,应该把该字段作为键(key)或是键的一部分; value的值可以提供给 Reduce 方法使用,也可能会出现在最终的结果中。 可以作为键的不仅是简单数据类型,也可以是任意的 JSON 对象。比如emit([doc.title, doc.price], doc)中,使用数组作为键。

map函数示例(javascript代码):

  1. function(doc) {
  2. emit(doc._id, doc);
  3. }

reduce函数

Reduce方法的参数有三个:key、values和rereduce,分别表示键、值和是否是rereduce 。 由于rereduce情况的存在,Reduce 方法一般需要处理两种情况:

传入的参数rereduce的值为false

这表明Reduce方法的输入是 Map方法输出的中间结果。

参数key的值是一个数组,对应于中间结果中的每条记录。 该数组的每个元素都是一个包含两个元素的数组,第一个元素是在Map方法中通过emit输出的键(key),第二个元素是记录所在的文档 ID 。

参数values的值是一个数组,对应于 Map 方法中通过emit输出的值(value)。

传入的参数rereduce的值为true

这表明Reduce方法的输入是上次Reduce方法的输出。

参数key的值为null。

参数values的值是一个数组,对应于上次Reduce方法的输出结果。

reduce函数示例(javascript代码):

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

实例解析

1、创建数据库testdb2,添加如下文档 :

  1. {
  2. "_id": "ef3c0dddfd988a9fa5dd77452a46a5e6",
  3. "phoneNumber": "1001",
  4. "billSeconds": 180,
  5. "timestamp": "201408251705"
  6. }
  7. {
  8. "_id": "ef3c0dddfd988a9fa5dd77452a482dd0",
  9. "phoneNumber": "1001",
  10. "billSeconds": 100,
  11. "timestamp": "201408251715"
  12. }

上述是分机1001的两条CDR,记录了两次通话的billSeconds,如果要计算通话时长,需要将 phoneNumber作为key,billSeconds作为value进行map和reduce操作。

2、用map操作过滤数据

  1. function(doc) {
  2. emit(doc.phoneNumber, doc.billSeconds);
  3. }

map函数以phoneNumber参数作为key,以billSeconds作为value对数据库执行过滤操作。

3、用reduce计算结果

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

reduce函数执行聚合操作,将key相同的value进行求和。

完整view创建代码如下:

  1. {
  2. "_id": "_design/jsTest",
  3. "language": "javascript",
  4. "views": {
  5. "all": {
  6. "map": "function(doc) { emit(doc.phoneNumber, doc.billSeconds); }",
  7. "reduce": "function (key, values, rereduce) { return sum(values); }"
  8. }
  9. }
  10. }

查询结果

单独执行map的结果:

  1. curl http://127.0.0.1:5984/testdb2/_design/jsTest/_view/all?reduce=false
  2. {"total_rows":2,"offset":0,"rows":[
  3. {"id":"ef3c0dddfd988a9fa5dd77452a46a5e6","key":"1001","value":180},
  4. {"id":"ef3c0dddfd988a9fa5dd77452a482dd0","key":"1001","value":100}
  5. ]}

map-reduce结果:

  1. curl http://127.0.0.1:5984/testdb2/_design/jsTest/_view/all?group=true
  2. {"rows":[
  3. {"key":"1001","value":280}
  4. ]}

视图类别

临时视图

python示例:

  1. import couchdb
  2. server = couchdb.Server("http://192.168.131.121:5984")
  3. db = server.create('python-tests')
  4. db['johndoe'] = dict(type='Person', name='John Doe')
  5. db['maryjane'] = dict(type='Person', name='Mary Jane')
  6. db['gotham'] = dict(type='City', name='Gotham City')
  7. map_fun = '''function(doc) {
  8. if (doc.type == 'Person')
  9. emit(doc.name, null);
  10. }'''
  11. for row in db.query(map_fun):
  12. print(row.key)
  13. del server['python-tests']

BigCouch不支持临时视图

永久视图

python示例:

  1. import couchdb
  2. server = couchdb.Server("http://192.168.131.121:5984")
  3. db = server.create('python-tests')
  4. db['johndoe'] = dict(type='Person', name='John Doe')
  5. db['maryjane'] = dict(type='Person', name='Mary Jane')
  6. db['gotham'] = dict(type='City', name='Gotham City')
  7. viewData = {
  8. "getdata":{
  9. "map":"function(doc){ if (doc.type == 'Person') emit(doc.name, null);}"
  10. }
  11. }
  12. db['_design/example'] = dict(language='javascript', views=viewData)
  13. for row in db.view('example/getdata'):
  14. print(row.key)
  15. del server['python-tests']

视图实现语言

javascript实现

couchDB默认的查询语言是javascript,不需要进行配置即可使用js创建视图。

示例代码:

  1. {
  2. "_id": "_design/jsTest",
  3. "language": "javascript",
  4. "views": {
  5. "all": {
  6. "map": "function(doc) { emit(doc._id, doc); }",
  7. "reduce": "function (key, values, rereduce) { return values.length; }"
  8. }
  9. }
  10. }

erlang实现

编辑local.ini文件,添加如下配置:

  1. [native_query_servers]
  2. erlang = {couch_native_process, start_link, []}

配置后需要重启couchDB服务器。

示例代码:

  1. {
  2. "_id": "_design/erlangTest",
  3. "language": "erlang",
  4. "views": {
  5. "all": {
  6. "map": "%% Map Function\nfun({Doc}) ->\n V = proplists:get_value(<<\"_id\">>, Doc, null),\n Emit(V,{Doc})\nend.\n\n",
  7. "reduce": "%% Reduce Function\nfun(Keys, Values, ReReduce) -> length(Values) end."
  8. }
  9. }
  10. }

python实现

安装couchdb-python包:

  1. pip install pycouchdb
  2. or
  3. pip install -i http://simple.crate.io/ pycouchdb
  4. or
  5. git clone git://github.com/niwibe/py-couchdb.git
  6. cd py-couchdb
  7. python setup.py install

编辑local.ini文件,添加如下配置:

  1. [query_servers]
  2. python=/usr/bin/couchpy

配置后需要重启couchDB服务器。

示例代码:

  1. {
  2. "_id": "_design/pythonTest",
  3. "language": "python",
  4. "views": {
  5. "all": {
  6. "map": "def fun(doc):\n yield doc['_id'],doc\n",
  7. "reduce": "def fun(key, values, rereduce):\n return len(values)\n"
  8. }
  9. }
  10. }

视图的使用

运行视图的可选参数

  1. key 限定结果中只包含键为该参数值的记录。
  2. startkey 限定结果中只包含键大于或等于该参数值的记录。
  3. endkey 限定结果中只包含键小于或等于该参数值的记录。
  4. limit 限定结果中包含的记录的数目。
  5. descending 指定结果中记录是否按照降序排列。
  6. skip 指定结果中需要跳过的记录数目。
  7. group 指定是否对键进行分组。
  8. reduce 指定reduce=false可以只返回 Map 方法的运行结果。

示例数据:

  1. {
  2. "_id": "ef3c0dddfd988a9fa5dd77452a46a5e6",
  3. "phoneNumber": "1001",
  4. "billSeconds": 180,
  5. "timestamp": "201408251705"
  6. }
  7. {
  8. "_id": "ef3c0dddfd988a9fa5dd77452a482dd0",
  9. "phoneNumber": "1001",
  10. "billSeconds": 100,
  11. "timestamp": "201408251715"
  12. }
  13. {
  14. "_id": "ef3c0dddfd988a9fa5dd77452a63a9e3",
  15. "phoneNumber": "1002",
  16. "billSeconds": 180,
  17. "timestamp": "201408251735"
  18. }
  19. {
  20. "_id": "5fecc0d7fe5acac6b46359b5eec4f3ff",
  21. "phoneNumber": "1003",
  22. "billSeconds": 190,
  23. "timestamp": "201408261035"
  24. }
  25. {
  26. "_id": "_design/jsTest",
  27. "language": "javascript",
  28. "views": {
  29. "all": {
  30. "map": "function(doc) { emit(doc.phoneNumber, doc.billSeconds); }",
  31. "reduce": "function (key, values, rereduce) {return sum(values); }"
  32. }
  33. }
  34. }

查找单个文档

语法:

  1. /database/_design/designdocname/_view/viewname?key="${key}"

示例:

  1. curl "http://192.168.131.121:5984/testdb2/_design/jsTest/_view/all?group=true&key=\"1001\""
  2. {"rows":[
  3. {"key":"1001","value":280}
  4. ]}

查找多个文档

语法:

  1. /database/_design/designdocname/_view/viewname?startkey="${startkey}"&endkey="${endkey}"

示例:

  1. curl "http://192.168.131.121:5984/testdb2/_design/jsTest/_view/all?group=true&startkey=\"1001\"&endkey=\"1002\""
  2. {"rows":[
  3. {"key":"1001","value":280},
  4. {"key":"1002","value":180}
  5. ]}
  6. curl "http://192.168.131.121:5984/testdb2/_design/jsTest/_view/all?group=true&startkey=\"1001\""
  7. {"rows":[
  8. {"key":"1001","value":280},
  9. {"key":"1002","value":180},
  10. {"key":"1003","value":190}
  11. ]}
  12. curl "http://192.168.131.121:5984/testdb2/_design/jsTest/_view/all?group=true&endkey=\"1002\""
  13. {"rows":[
  14. {"key":"1001","value":280},
  15. {"key":"1002","value":180}
  16. ]}

本文github地址:

https://github.com/mike-zhang/mikeBlogEssays/blob/master/2014/20141007_couchDB视图.md

欢迎补充

couchDB视图的更多相关文章

  1. couchDB文档

    每个文档都是自包含的数据单元,是一系列数据项的集合. 每个数据项都有一个名称与对应的值,值既可以是简单的数据类型,如字符串.数字和日期等:也可以是复杂的类型,如有序列表和关联对象. 每个文档都有一个全 ...

  2. CouchDB简单应用

    CouchDB是众多称作NoSQL解决方案中的一员.与众不同的是,CouchDB是一个面向文档的数据库,在它里面所有文档域(Field)都是以键值对的形式存储的.域(Field)可以是一个简单的键值对 ...

  3. CouchDB 简单HTTP接口使用说明

    目录 1.简介 2.安装 2.HTTP接口简单使用 2.1.认证接口 2.1.1 Basic Authentication 2.1.2 Cookie Authentication 2.2 创建与删除数 ...

  4. CouchDB学习-介绍

    官方文档 CouchDB 1文档存储 CouchDB服务器主机是一个存储文档的数据库.每一个文档在数据库中都有唯一的名字.CouchDB提供RESTful HTTP API用来读取和更新(添加,编辑, ...

  5. CouchDB学习一

    端口 端口号 协议 作用 5984 tcp 标椎集群端口用于所有的HTTP API请求 5986 tcp 用于管理员对节点与分片的管理 4369 tcp Erlang端口到daemon的映射 配置介绍 ...

  6. CouchDB简介

    类型:开源数据库,Apache项目 存储格式:JSON 查询语言:JavaScript API :MapReduce.HTTP 特点 MVCC(Multiversion concurrency con ...

  7. apache开源项目--CouchDB

    Apache CouchDB 是一个面向文档的数据库管理系统.它提供以 JSON 作为数据格式的 REST 接口来对其进行操作,并可以通过视图来操纵文档的组织和呈现. CouchDB 是 Apache ...

  8. 84. 从视图索引说Notes数据库(下)

    作用和代价上文介绍了关系型数据库里的索引.Notes数据库里的索引隐藏在视图概念里(本文的讨论仅仅针对Notes的视图索引,不包括全文索引.).开发者创建的视图仅仅是存放在数据库里的一条设计文档.数据 ...

  9. 对比Cassandra、 Mongodb、CouchDB、Redis、Riak、 Membase、Neo4j、HBase

    转自:http://www.cnblogs.com/alephsoul-alephsoul/archive/2013/04/26/3044630.html 导读:Kristóf Kovács 是一位软 ...

随机推荐

  1. 2000条你应知的WPF小姿势 基础篇<69-73 WPF Freeze机制和Template>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000ThingsYou Should Know About C# 和 2,00 ...

  2. 大型网站的灵魂——性能

    前言     在前一篇随笔<大型网站系统架构的演化>中,介绍了大型网站的演化过程,期间穿插了一些技术和手段,我们可以从中看出一个大型网站的轮廓,但想要掌握设计开发维护大型网站的技术,需要我 ...

  3. idea怎么设置自己的名字和时间

    1.直接修改idea64.exe.vmoptions 里面添加上 -Duser.name=yourname 重启即可生效 1.file - settings-Editor- File and Code ...

  4. webpack入门之简单例子跑起来

    webpack介绍 Webpack是当下最热门的前端资源模块化管理和打包工具,它可以将很多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源,还可以将按需加载的模块进行代码分割,等到实际需要的时 ...

  5. 【java】细说 JAVA中 标注 注解(annotation)

    Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用 下面我们来详细说说这个注解,到底是怎么一 ...

  6. ASP.NET 页面禁止被 iframe 框架引用

    两个站点: a.sample.com b.sample.com a.sample.com 站点中的一段示例 JS 代码: var iframe = document.createElement(&qu ...

  7. # ios开发 @property 和 Ivar 的区别

    ios开发 @property 和 Ivar 的区别 @property 属性其实是对成员变量的一种封装.我们先大概这样理解: @property = Ivar + setter + getter I ...

  8. Android 中关于Fragment嵌套Fragment的问题

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5802146.html 问题描述: 在项目中Activity A中嵌套Fragment B,Fragment ...

  9. Linux内核配置、编译及Makefile简述

    Hi,大家好!我是CrazyCatJack.最近在学习Linux内核的配置.编译及Makefile文件.今天总结一下学习成果,分享给大家^_^ 1.解压缩打补丁 首先是解压缩你获取到的Linux内核. ...

  10. 数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇

    HT 是啥:Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心目中的产品方向,接着就朝这个方向慢慢打 ...