CouchDB从设计文档中读取配置

CouchDB从设计文档中读取配置,couchdb,Couchdb,我想在配置文件中存储一个值,并在设计文档中查找它,以便与更新值进行比较。我相信我已经看到了这一点,但是,就我的一生而言,我似乎不记得该怎么做 更新 我意识到(在第一次回答之后)有不止一种方式来解释我的问题。希望这个例子能澄清一点。给定一个配置: curl -X PUT http://localhost:5984/_config/shared/token -d '"0123456789"' 然后我希望能够在我的设计文档中查找它 { "_id": "_design/loadsecrets",

我想在配置文件中存储一个值,并在设计文档中查找它,以便与更新值进行比较。我相信我已经看到了这一点,但是,就我的一生而言,我似乎不记得该怎么做

更新

我意识到(在第一次回答之后)有不止一种方式来解释我的问题。希望这个例子能澄清一点。给定一个配置:

curl -X PUT http://localhost:5984/_config/shared/token -d '"0123456789"'
然后我希望能够在我的设计文档中查找它

{
  "_id": "_design/loadsecrets",
  "validate_doc_update": {
    "test": function (newDoc,oldDoc) { 
       if (newDoc.supersecret != magicobject.config.shared.token){
         throw({unauthorized:"You don't know the super secret"});
       } 
    }
  }
}
这是我正在寻找的像
magicobject.config.shared.token
这样的功能

更新2

另一个可能有用(人为)的场景

然后在跟踪员工行为的设备上:

{
  "_id": "_design/logger",
  "updates": {
    "logger": function (doc,req) { 
      if (!doc) {
        doc = {_id:req.id};
      }
      if(req.level < magicobject.config.eventlogger.detaillevel ){
        doc.details = req.details;
      }
      return [doc, req.details];
    }
  }
}
{
“_id”:“_设计/记录器”,
“更新”:{
“记录器”:功能(文件,请求){
如果(!doc){
doc={u id:req.id};
}
if(req.level
我想我知道你在说什么,如果我是对的,那么你的要求就不可能了。(至少在v1.6和v2.0中,我不确定该功能何时被删除)

有一个鲜为人知的技巧,允许查看/显示/列表/验证/etc函数在函数中以
this
的形式访问父设计文档。例如:

{
  "_id": "_design/hello-world",
  "config": {
    "PI": 3.14
  },
  "views": {
    "test": {
      "map": "function (doc) { emit(this.config.PI); })"
    }
  }
}
这是一个非常疯狂的想法,我想它被删除了,因为它在设计文档和视图代码之间创建了一个循环依赖关系,使得使视图索引无效/重建的过程变得非常棘手

我记得在很久以前的某个时候使用过这个技巧,但是现在这个功能肯定已经消失了。(而且可能永远不会回来)

我想我知道你在说什么,如果我是对的,那么你所要求的就不可能了。(至少在v1.6和v2.0中,我不确定该功能何时被删除)

有一个鲜为人知的技巧,允许查看/显示/列表/验证/etc函数在函数中以
this
的形式访问父设计文档。例如:

{
  "_id": "_design/hello-world",
  "config": {
    "PI": 3.14
  },
  "views": {
    "test": {
      "map": "function (doc) { emit(this.config.PI); })"
    }
  }
}
这是一个非常疯狂的想法,我想它被删除了,因为它在设计文档和视图代码之间创建了一个循环依赖关系,使得使视图索引无效/重建的过程变得非常棘手

我记得在很久以前的某个时候使用过这个技巧,但是现在这个功能肯定已经消失了。(而且可能永远不会回来)

对于您的特殊用例(使用秘密令牌验证文档),可能有一个解决方法,但我不确定令牌是否会在某个地方泄漏。这完全取决于您的安全需求是什么

您可以滥用第4个参数来验证\u doc\u update,securityObject(请参阅)将秘密令牌存储为第一个管理员名称:

{
  "test": "function (newDoc, oldDoc, userCtx, secObj) {
    var token = secObj.admins.names[0];
    if (newDoc.supersecret != token) {
      throw({unauthorized:"You don't know the super secret"});
    }
  }"
}
因此,如果将db的安全对象设置为
{admins:{names:[“s3cr3t-t0k3n”],roles:[“\u admin”]}
,则必须将“s3cr3t-t0k3n”作为文档的超级机密属性传递

这显然是一个肮脏的黑客行为,但据我所知,安全对象只能由管理员读取或修改,您不会立即将您的令牌泄漏给公众。但是,如果需要“真实”的安全性,请在CouCHDB和调用方之间添加一个单独的层。

对于您的特殊用例(用一个秘密令牌验证文档),可能会有一个解决方案,但我不确定令牌是否可能在某个地方泄漏。这完全取决于您的安全需求是什么

您可以滥用第4个参数来验证\u doc\u update,securityObject(请参阅)将秘密令牌存储为第一个管理员名称:

{
  "test": "function (newDoc, oldDoc, userCtx, secObj) {
    var token = secObj.admins.names[0];
    if (newDoc.supersecret != token) {
      throw({unauthorized:"You don't know the super secret"});
    }
  }"
}
因此,如果将db的安全对象设置为
{admins:{names:[“s3cr3t-t0k3n”],roles:[“\u admin”]}
,则必须将“s3cr3t-t0k3n”作为文档的超级机密属性传递


这显然是一个肮脏的黑客行为,但据我所知,安全对象只能由管理员读取或修改,您不会立即将您的令牌泄漏给公众。但是,如果需要“真实”的安全性,请考虑在CouCHDB和调用方之间添加一个单独的层。

< P>这是我最后一个答案的后续,更一般的信息是:


没有使用配置的通用方法,因为CouchDB的设计考虑了可伸缩性、稳定性和可预测性。它的设计使用了和的许多原理,尽可能避免副作用。这是件好事™.

但是,根据调用函数的上下文,每种类型的函数都有可以使用的附加参数:

  • ,并为每个请求执行函数,因此它们获取请求对象。这里有
    req.secObj
    req.userCtx
    to(ab)用于公共配置。另外,AFAIK将
    这个
    关键字设置为当前的设计文档,这样您就可以使用设计文档来获得通用配置(至少在CouchDB 1.6版本之前它是有效的)
  • 函数(map、reduce)没有其他参数,因为视图的结果会写入磁盘并在后续调用中重用。映射函数必须是纯函数(因此不要使用例如
    Math.random()
    )。对于单个设计文档中跨视图函数的共享配置,您可以使用CommonJS
    require()
    ,但只能使用
  • 函数不一定在用户触发的http请求中执行(它们在每次写入之前被调用,这可能不是仅通过http触发的)。因此,他们在函数签名中添加了
    userCtx
    secObj
    作为单独的参数
综上所述,您可以使用以下位置进行配置:

curl -X PUT http://localhost:5984/_config/shared/token -d '"0123456789"'
  • userCtx
    用于用户特定配置。使用特殊角色(例如带有前缀)存储小的配置位。例如,它就是这样做的
  • secObj
    用于数据库范围的配置。使用s