简体   繁体   English

如何干掉CouchDB视图?

[英]How do I DRY up my CouchDB views?

What can I do to share code among views in CouchDB? 如何在CouchDB中的视图之间共享代码?

Example 1 -- utility methods 例1 - 实用方法

Jesse Hallett has some good utility methods , including Jesse Hallett 有一些很好的实用方法 ,包括

function dot(attr) {
  return function(obj) {
      return obj[attr];
  }
}

Array.prototype.map = function(func) {
  var i, r = [],
  for (i = 0; i < this.length; i += 1) {
    r[i] = func(this[i]);
  }
  return r;
};

...

Where can I put this code so every view can access it? 我在哪里可以放置此代码,以便每个视图都可以访问它?

Example 2 -- constants 例2 - 常量

Similarly for constants I use in my application. 类似于我在我的应用程序中使用的常量。 Where do I put 我在哪里放

MyApp = {
  A_CONSTANT = "...";
  ANOTHER_CONSTANT = "...";
};

Example 3 -- filter of a filter: 例3 - 过滤器的过滤器:

What if I want a one view that filters by "is this a rich person?": 如果我想要一个过滤“是这个有钱人吗?”的视图怎么办?

function(doc) {
  if (doc.type == 'person' && doc.net_worth > 1000000) {
    emit(doc.id, doc);
  }
}

and another that indexes by last name: 和另一个按姓氏索引:

function(doc) {
  if (doc.last_name) {
    emit(doc.last_name, doc);
  }
}

How can I combine them into a "rich people by last name" view? 我怎样才能将它们组合成一个“姓氏丰富的人”视角?

I sort of want the equivalent of the Ruby 我想要相当于Ruby

my_array.select { |x| x.person? }.select { |x| x.net_worth > 1,000,000 }.map { |x| [x.last_name, x] }

How can I be DRYer? 我怎么能干嘛?

As per this blog post , you can add commonjs modules to the map function (but not the reduce function) in views in couchdb 1.1 by having a key called lib in your views object. 根据这篇博文 ,你可以通过在views对象中使用一个名为lib的键,将commonjs模块添加到couchdb 1.1视图中的map函数 (但不是reduce函数)中。 A lot of popular javascript libraries like underscore.js adhere to the commonjs standard, so you can use them in your views by using require("views/lib/[your module name]") . 许多流行的javascript库(如underscore.js)都遵循commonjs标准,因此您可以使用require(“views / lib / [your module name]”)在视图中使用它们。

Say you include underscore.js as "underscore" in the lib object in views, like so: 假设您在视图中的lib对象中包含underscore.js作为“下划线”,如下所示:

views: {
    lib: {
         underscore: "// Underscore.js 1.1.6\n ...
    }
    ...
    [ the rest of your views go here]
}

, you can then add the following to your view to get access to the _ module: ,然后,您可以将以下内容添加到视图中以访问_模块:

var _ = require("views/lib/underscore");

For custom libraries, all you need to do is make anything you want to share in your library a value to the global "exports" object. 对于自定义库,您需要做的就是将要在库中共享的任何内容作为全局“exports”对象的值。

From the CouchDB Wiki : 来自CouchDB Wiki

There are no development plans to share code/functions between views. 没有开发计划在视图之间共享代码/功能。 Each view function is stored according to a hash of their byte representation, so it is important that a function does not load any additional code, changing its behavior without changing its byte-string. 每个视图函数都是根据其字节表示的哈希值存储的,因此重要的是函数不会加载任何其他代码,在不更改其字节字符串的情况下更改其行为。 Hence the use-case for CouchApp . 因此CouchApp的用例。

The answer lies in couchapp . 答案在于couchapp With couchapp you can embed macros that include common library code into any of the design document sections. 使用couchapp,您可以将包含公共库代码的宏嵌入到任何设计文档部分中。 It is done before the design document is submitted to the server. 它是在将设计文档提交给服务器之前完成的。 What you need to do to do the query you ask about is reverse the keys that are emitted so you can do a range query on the "network" 您要询问的查询需要做的是反转发出的键,以便在“网络”上进行范围查询

function(doc) 
{
  if (doc.type == 'person') 
  {
    emit([doc.net_worth, doc.lastname], null);
  }
}

You don't want to include the doc you can do that with include_docs=true on the query parameters. 您不希望在查询参数中包含可以使用include_docs=true执行此操作的文档。 And you get the doc.id for free as part of the key. 并且您可以免费获得doc.id作为密钥的一部分。 Now you can do a range query on networth which would look something like this. 现在你可以在networth上进行范围查询,看起来像这样。

http://localhost:5984/database/_design/people/_view/by_net_worth?startkey=[1000000]&endkey=[{},{}]&include_docs=true

Couchapp will "macro" in libraries, and it works pretty well. Couchapp将在图书馆中“宏观”,而且效果非常好。

The other, unsupported option is to add utility functions like that to a custom query server. 另一个不受支持的选项是将类似的实用程序功能添加到自定义查询服务器。 The JS file is not that difficult to understand, and the Ruby and Python versions are even simpler. JS文件并不难理解,Ruby和Python版本更简单。 The view server compiles the strings in the design doc into function objects as they are executed, so if you close those functions over utility functions, constants or whatever, they'll be executable in map/reduce/show/list functions. 视图服务器在执行时将设计文档中的字符串编译为函数对象,因此如果您通过实用函数,常量或其他函数关闭这些函数,它们将在map / reduce / show / list函数中执行。

Look for the place in the main.js file where "emit" and "log" are defined, and emulate the definition of those functions to expose your custom utility functions to your map and reduce lambdas. 在main.js文件中查找定义“emit”和“log”的位置,并模拟这些函数的定义以将自定义实用程序函数公开给地图并减少lambdas。

Caveat: Changing the view server without requiring a rebuild on your view will mean that your view index will not be correct. 警告:更改视图服务器而不需要在视图上进行重建将意味着您的视图索引将不正确。 Programmer Beware. 程序员要小心。

You can't do this (last I checked) because the views are stored in the database, and the key for the view is a hash of itself. 你不能这样做(最后我检查过),因为视图存储在数据库中,视图的键是它自己的哈希。 A view cannot rely on outside data/logic/programming, because if it changes then the view is different and won't match. 视图不能依赖外部数据/逻辑/编程,因为如果它发生变化,那么视图就会不同并且不匹配。 It confused me, and still does, so I may be wrong. 它让我困惑,但仍然如此,所以我可能错了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM