• couchDB视图


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

    视图函数

    map函数

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

    map函数示例(javascript代码):

    function(doc) {
      emit(doc._id, doc);
    }
    

    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代码):

    function (key, values, rereduce) {
        return sum(values);
    }
    

    实例解析

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

    {
       "_id": "ef3c0dddfd988a9fa5dd77452a46a5e6", 
       "phoneNumber": "1001",
       "billSeconds": 180,
       "timestamp": "201408251705"
    }
    
    {
       "_id": "ef3c0dddfd988a9fa5dd77452a482dd0",
       "phoneNumber": "1001",
       "billSeconds": 100,
       "timestamp": "201408251715"
    }
    

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

    2、用map操作过滤数据

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

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

    3、用reduce计算结果

    function (key, values, rereduce) 
    {   
        return sum(values); 
    }
    

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

    完整view创建代码如下:

    {
       "_id": "_design/jsTest", 
       "language": "javascript",
       "views": {
           "all": {
               "map": "function(doc) {  emit(doc.phoneNumber, doc.billSeconds); }",
               "reduce": "function (key, values, rereduce) {   return sum(values); }"
           }
       }
    }
    

    查询结果

    单独执行map的结果:

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

    map-reduce结果:

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

    视图类别

    临时视图

    python示例:

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

    BigCouch不支持临时视图

    永久视图

    python示例:

    import couchdb
    
    server = couchdb.Server("http://192.168.131.121:5984")
    db = server.create('python-tests')
    
    db['johndoe'] = dict(type='Person', name='John Doe')
    db['maryjane'] = dict(type='Person', name='Mary Jane')
    db['gotham'] = dict(type='City', name='Gotham City')
    
    viewData = {
    "getdata":{
        "map":"function(doc){ if (doc.type == 'Person') emit(doc.name, null);}"
     }
    }
    db['_design/example'] = dict(language='javascript', views=viewData)
    
    for row in db.view('example/getdata'):
        print(row.key)
    
    del server['python-tests']
    

    视图实现语言

    javascript实现

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

    示例代码:

    {
       "_id": "_design/jsTest", 
       "language": "javascript",
       "views": {
           "all": {
               "map": "function(doc) {  emit(doc._id, doc); }",
               "reduce": "function (key, values, rereduce) {   return values.length; }"
           }
       }
    }
    

    erlang实现

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

    [native_query_servers]
    erlang = {couch_native_process, start_link, []}
    

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

    示例代码:

    {
       "_id": "_design/erlangTest",
       "language": "erlang",
       "views": {
           "all": {
               "map": "%% Map Function
    fun({Doc}) ->
      V = proplists:get_value(<<"_id">>, Doc, null),
      Emit(V,{Doc})
    end.
    
    ",
               "reduce": "%% Reduce Function
    fun(Keys, Values, ReReduce) -> length(Values) end."
           }
       }
    }
    

    python实现

    安装couchdb-python包:

    pip install pycouchdb
    
    or
    
    pip install -i http://simple.crate.io/ pycouchdb
    
    or
    
    git clone git://github.com/niwibe/py-couchdb.git
    cd py-couchdb
    python setup.py install
    

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

    [query_servers]
    python=/usr/bin/couchpy
    

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

    示例代码:

    {
       "_id": "_design/pythonTest",       
       "language": "python",
       "views": {
           "all": {
               "map": "def fun(doc):
        yield doc['_id'],doc
    ",
               "reduce": "def fun(key, values, rereduce):
        return len(values)
    "               
           }
       }
    }
    

    视图的使用

    运行视图的可选参数

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

    示例数据:

    {
       "_id": "ef3c0dddfd988a9fa5dd77452a46a5e6", 
       "phoneNumber": "1001",
       "billSeconds": 180,
       "timestamp": "201408251705"
    }
    
    {
       "_id": "ef3c0dddfd988a9fa5dd77452a482dd0",
       "phoneNumber": "1001",
       "billSeconds": 100,
       "timestamp": "201408251715"
    }
    
    {
       "_id": "ef3c0dddfd988a9fa5dd77452a63a9e3",
       "phoneNumber": "1002",
       "billSeconds": 180,
       "timestamp": "201408251735"
    }
    
    {
       "_id": "5fecc0d7fe5acac6b46359b5eec4f3ff",
       "phoneNumber": "1003",
       "billSeconds": 190,
       "timestamp": "201408261035"
    }
    
    {
       "_id": "_design/jsTest",
       "language": "javascript",
       "views": {
           "all": {
               "map": "function(doc) {  emit(doc.phoneNumber, doc.billSeconds); }",
               "reduce": "function (key, values, rereduce) {return sum(values); }"
           }
       }
    }
    

    查找单个文档

    语法:

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

    示例:

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

    查找多个文档

    语法:

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

    示例:

    curl "http://192.168.131.121:5984/testdb2/_design/jsTest/_view/all?group=true&startkey="1001"&endkey="1002""
    
    {"rows":[
    {"key":"1001","value":280},
    {"key":"1002","value":180}
    ]}
    
    curl "http://192.168.131.121:5984/testdb2/_design/jsTest/_view/all?group=true&startkey="1001""
    
    {"rows":[
    {"key":"1001","value":280},
    {"key":"1002","value":180},
    {"key":"1003","value":190}
    ]}
    
    curl "http://192.168.131.121:5984/testdb2/_design/jsTest/_view/all?group=true&endkey="1002""
    
    {"rows":[
    {"key":"1001","value":280},
    {"key":"1002","value":180}
    ]}

    本文github地址:

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

    欢迎补充

  • 相关阅读:
    angular源码分析:angular中$rootscope的实现——scope的一生
    angular源码分析:图解angular的启动流程
    angular源码分析:angular的整个加载流程
    angular源码分析:injector.js文件分析——angular中的依赖注入式如何实现的(续)
    angular源码分析:angular中jqLite的实现——你可以丢掉jQuery了
    第二章:互联网的进化成型
    angular源码分析:angular的源代码目录结构说明
    angular源码分析:angular中各种常用函数,比较省代码的各种小技巧
    angular源码分析:angular中的依赖注入式如何实现的
    【Linux】Shell基础命令、文件软(硬)链接的理解
  • 原文地址:https://www.cnblogs.com/MikeZhang/p/couchdbView20141008.html
Copyright © 2020-2023  润新知