erlang 使用curl只复制couchDB中的一些文档

qzwqbdag  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(255)

文档中说我可以使用选择器语法将一个数据库部分复制到另一个数据库,并且它的工作原理与_find命令相同,所以我首先使用_find进行了测试。
我知道要复制的文档的_id,但是有足够多的文档需要使用正则表达式。
我能够让这个命令工作:

curl -H 'Content-Type: application/json' -d "{\"selector\":{\"_id\":\"doc-A\"}}" http://admin:PW@127.0.0.1:5984/mydb/_find

但不是我的regex尝试;我想得到"doc-A"、"doc-B"、"doc-XYZ"......以及"其他-这个"、"其他-那个"等等。

curl -H 'Content-Type: application/json' -d "{\"selector\":{\"_id\":{\"$regex\":\"^(doc-|other-)\"}}}" http://admin:PW@127.0.0.1:5984/mydb/_find

我得到的错误看起来很糟糕:

{"error":"badmatch","reason":"{error,{{mango_error,mango_util,{invalid_field_name,<<\"_id.\">>}},
  nil,
  [{mango_util,check_non_empty,2,
               [{file,\"src/mango_util.erl\"},{line,399}]},
   {mango_util,parse_field,1,[{file,\"src/mango_util.erl\"},{line,382}]},
   {mango_doc,get_field,3,[{file,\"src/mango_doc.erl\"},{line,375}]},
   {mango_selector,match,3,[{file,\"src/mango_selector.erl\"},{line,572}]},
   {mango_cursor_view,view_cb,2,
                      [{file,\"src/mango_cursor_view.erl\"},{line,257}]},
   {couch_mrview,map_fold,3,[{file,\"src/couch_mrview.erl\"},{line,491}]},
   {couch_bt_engine,include_reductions,4,
                    [{file,\"src/couch_bt_engine.erl\"},{line,1170}]},
   {couch_bt_engine,skip_deleted,4,
                    [{file,\"src/couch_bt_engine.erl\"},{line,1165}]}]}}","ref":2902755775}

它似乎在说我不能使用_id来过滤?
我有一个简短的Erlang正则表达式的支持,似乎它会涵盖我想在这里实现什么?
我正在Ubuntu和Mint上运行couchdb 3.1.1。
退一步说,因为我不是按文档内容选择,而是按_id选择,这应该更容易,我想知道是否有更容易的方法来完成部分复制?
我需要编写脚本,所以理想情况下希望用curl命令完成它。但是,如果这是完成工作的唯一方法,我可以使用node + nano脚本,或者安装另一个工具。

chhkpiq4

chhkpiq41#

感谢@RamblinRose在评论中的提示,原来这是因为没有转义\"$regex\"中的$。(这里所有的例子都使用bash-escaping。)
更改为\"\$regex\"是有效的,但更简单的方法是用单引号代替双引号将JSON括起来,然后"$都不需要转义:

curl -H 'Content-Type: application/json' \
  -d '{"selector":{"_id":{"$regex":"^(doc-|other-)"}}}' \
  http://admin:PW@127.0.0.1:5984/mydb/_find

为了回答我的主要问题,下面介绍如何使用curl设置过滤复制:

export ADMINDB='http://admin:PASSWORD@127.0.0.1:5984'
curl -H 'Content-Type: application/json' \
  -d '{"source": "'${ADMINDB}'/db_one", "target": "'${ADMINDB}'/db_two", "selector":{"_id":{"$regex":"^(doc-|other-)"}} "create_target": false, "continuous": false}' \
  ${ADMINDB}/_replicator

注意:导出时的前导空格,所以密码不输入bash历史。
注意:${ADMINDB}周围的单引号,以便变量插入工作,同时仍然能够使用单引号,而不是乱用反斜杠。
注意:版本号从db_one延续到db_two,但我最终在已经存在的文档上产生了冲突。
更严重的是,如果我编辑db_two中的"doc-A",例如将其从rev-72移到rev-74,然后再次运行replicate命令,它不会被替换。甚至不会发生冲突。它会与新数据一起保留在rev-74中。如果我删除db_two中的文档,然后运行replicate命令,它们会在db_two中保持删除状态。
如果你只是想把一些文档从一个数据库复制到另一个数据库,如果它们已经存在,就强制替换它们,这不是CouchDB方式,你不能这样做(用_replicate)。

相关问题