KITAITI Makoto
null+****@clear*****
Sun Nov 15 23:29:56 JST 2015
KITAITI Makoto 2015-11-15 23:29:56 +0900 (Sun, 15 Nov 2015) New Revision: bd72fdd325bf1fa69c903d31d009f6927072575c https://github.com/droonga/droonga.org/commit/bd72fdd325bf1fa69c903d31d009f6927072575c Merged 83212a0: Merge pull request #20 from KitaitiMakoto/typos Message: Generate and update files for v1.1.2 Japanese edition % rake Added files: _po/ja/reference/command-line-tools/drndump/index.po _po/ja/reference/command-line-tools/droonga-add/index.po _po/ja/reference/command-line-tools/droonga-engine-absorb-data/index.po _po/ja/reference/command-line-tools/droonga-engine-catalog-generate/index.po _po/ja/reference/command-line-tools/droonga-engine-catalog-modify/index.po _po/ja/reference/command-line-tools/droonga-engine-configure/index.po _po/ja/reference/command-line-tools/droonga-engine-join/index.po _po/ja/reference/command-line-tools/droonga-engine-set-role/index.po _po/ja/reference/command-line-tools/droonga-engine-unjoin/index.po _po/ja/reference/command-line-tools/droonga-groonga/index.po _po/ja/reference/command-line-tools/droonga-http-server-configure/index.po _po/ja/reference/command-line-tools/droonga-request/index.po _po/ja/reference/command-line-tools/droonga-send/index.po _po/ja/reference/command-line-tools/droonga-system-status/index.po _po/ja/reference/command-line-tools/index.po _po/ja/tutorial/add-replica/index.po _po/ja/tutorial/dump-restore/index.po ja/reference/1.1.2/catalog/index.md ja/reference/1.1.2/catalog/version1/index.md ja/reference/1.1.2/catalog/version2/index.md ja/reference/1.1.2/command-line-tools/drndump/index.md ja/reference/1.1.2/command-line-tools/droonga-add/index.md ja/reference/1.1.2/command-line-tools/droonga-engine-absorb-data/index.md ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-generate/index.md ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-modify/index.md ja/reference/1.1.2/command-line-tools/droonga-engine-configure/index.md ja/reference/1.1.2/command-line-tools/droonga-engine-join/index.md ja/reference/1.1.2/command-line-tools/droonga-engine-set-role/index.md ja/reference/1.1.2/command-line-tools/droonga-engine-unjoin/index.md ja/reference/1.1.2/command-line-tools/droonga-groonga/index.md ja/reference/1.1.2/command-line-tools/droonga-http-server-configure/index.md ja/reference/1.1.2/command-line-tools/droonga-request/index.md ja/reference/1.1.2/command-line-tools/droonga-send/index.md ja/reference/1.1.2/command-line-tools/droonga-system-status/index.md ja/reference/1.1.2/command-line-tools/index.md ja/reference/1.1.2/commands/add/index.md ja/reference/1.1.2/commands/column-create/index.md ja/reference/1.1.2/commands/column-list/index.md ja/reference/1.1.2/commands/column-remove/index.md ja/reference/1.1.2/commands/column-rename/index.md ja/reference/1.1.2/commands/delete/index.md ja/reference/1.1.2/commands/index.md ja/reference/1.1.2/commands/load/index.md ja/reference/1.1.2/commands/search/index.md ja/reference/1.1.2/commands/select/index.md ja/reference/1.1.2/commands/system/index.md ja/reference/1.1.2/commands/system/statistics/object/count/index.md ja/reference/1.1.2/commands/system/statistics/object/count/per-volume/index.md ja/reference/1.1.2/commands/system/status/index.md ja/reference/1.1.2/commands/table-create/index.md ja/reference/1.1.2/commands/table-list/index.md ja/reference/1.1.2/commands/table-remove/index.md ja/reference/1.1.2/http-server/index.md ja/reference/1.1.2/index.md ja/reference/1.1.2/message/index.md ja/reference/1.1.2/plugin/adapter/index.md ja/reference/1.1.2/plugin/collector/index.md ja/reference/1.1.2/plugin/error/index.md ja/reference/1.1.2/plugin/handler/index.md ja/reference/1.1.2/plugin/index.md ja/reference/1.1.2/plugin/matching-pattern/index.md ja/tutorial/1.1.2/add-replica/index.md ja/tutorial/1.1.2/basic/index.md ja/tutorial/1.1.2/benchmark/index.md ja/tutorial/1.1.2/dump-restore/index.md ja/tutorial/1.1.2/groonga/index.md ja/tutorial/1.1.2/index.md ja/tutorial/1.1.2/plugin-development/adapter/index.md ja/tutorial/1.1.2/plugin-development/handler/index.md ja/tutorial/1.1.2/plugin-development/index.md ja/tutorial/1.1.2/virtual-machines-for-experiments/index.md ja/tutorial/1.1.2/watch.md Modified files: _po/ja/reference/1.1.2/catalog/index.po _po/ja/reference/1.1.2/catalog/version1/index.po _po/ja/reference/1.1.2/catalog/version2/index.po _po/ja/reference/1.1.2/command-line-tools/drndump/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-add/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-engine-absorb-data/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-generate/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-modify/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-engine-configure/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-engine-join/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-engine-set-role/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-engine-unjoin/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-groonga/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-http-server-configure/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-request/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-send/index.po _po/ja/reference/1.1.2/command-line-tools/droonga-system-status/index.po Modified: _po/ja/reference/1.1.2/catalog/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/catalog/index.po 2015-11-15 23:24:28 +0900 (ba56f13) +++ _po/ja/reference/1.1.2/catalog/index.po 2015-11-15 23:29:56 +0900 (da6c573) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/catalog/version1/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/catalog/version1/index.po 2015-11-15 23:24:28 +0900 (1fc3172) +++ _po/ja/reference/1.1.2/catalog/version1/index.po 2015-11-15 23:29:56 +0900 (f79f002) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/catalog/version2/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/catalog/version2/index.po 2015-11-15 23:24:28 +0900 (0a2247a) +++ _po/ja/reference/1.1.2/catalog/version2/index.po 2015-11-15 23:29:56 +0900 (2af2300) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/drndump/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/drndump/index.po 2015-11-15 23:24:28 +0900 (638662a) +++ _po/ja/reference/1.1.2/command-line-tools/drndump/index.po 2015-11-15 23:29:56 +0900 (e45bca7) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-add/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-add/index.po 2015-11-15 23:24:28 +0900 (d576fac) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-add/index.po 2015-11-15 23:29:56 +0900 (27f5ea3) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-engine-absorb-data/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-engine-absorb-data/index.po 2015-11-15 23:24:28 +0900 (1fe7efd) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-engine-absorb-data/index.po 2015-11-15 23:29:56 +0900 (1253548) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-generate/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-generate/index.po 2015-11-15 23:24:28 +0900 (028c4e2) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-generate/index.po 2015-11-15 23:29:56 +0900 (3c07edd) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-modify/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-modify/index.po 2015-11-15 23:24:28 +0900 (22adecc) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-modify/index.po 2015-11-15 23:29:56 +0900 (c0b3c4c) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-engine-configure/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-engine-configure/index.po 2015-11-15 23:24:28 +0900 (a883785) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-engine-configure/index.po 2015-11-15 23:29:56 +0900 (5e7876d) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-engine-join/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-engine-join/index.po 2015-11-15 23:24:28 +0900 (20ac37a) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-engine-join/index.po 2015-11-15 23:29:56 +0900 (9460593) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-engine-set-role/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-engine-set-role/index.po 2015-11-15 23:24:28 +0900 (749adae) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-engine-set-role/index.po 2015-11-15 23:29:56 +0900 (d7c12a2) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-engine-unjoin/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-engine-unjoin/index.po 2015-11-15 23:24:28 +0900 (d34b839) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-engine-unjoin/index.po 2015-11-15 23:29:56 +0900 (41b6b7c) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-groonga/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-groonga/index.po 2015-11-15 23:24:28 +0900 (0f4bf77) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-groonga/index.po 2015-11-15 23:29:56 +0900 (f1601f7) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-http-server-configure/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-http-server-configure/index.po 2015-11-15 23:24:28 +0900 (8cf826b) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-http-server-configure/index.po 2015-11-15 23:29:56 +0900 (f0f30dd) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-request/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-request/index.po 2015-11-15 23:24:28 +0900 (c395fb8) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-request/index.po 2015-11-15 23:29:56 +0900 (6511cc2) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-send/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-send/index.po 2015-11-15 23:24:28 +0900 (8c6bce1) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-send/index.po 2015-11-15 23:29:56 +0900 (2a8de3a) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Modified: _po/ja/reference/1.1.2/command-line-tools/droonga-system-status/index.po (+1 -1) =================================================================== --- _po/ja/reference/1.1.2/command-line-tools/droonga-system-status/index.po 2015-11-15 23:24:28 +0900 (e73b391) +++ _po/ja/reference/1.1.2/command-line-tools/droonga-system-status/index.po 2015-11-15 23:29:56 +0900 (8d00bac) @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"PO-Revision-Date: 2014-11-30 23:19+0900\n" +"PO-Revision-Date: 2014-03-05 12:52+0900\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" Added: _po/ja/reference/command-line-tools/drndump/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/drndump/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-add/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-add/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-engine-absorb-data/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-engine-absorb-data/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-engine-catalog-generate/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-engine-catalog-generate/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-engine-catalog-modify/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-engine-catalog-modify/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-engine-configure/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-engine-configure/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-engine-join/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-engine-join/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-engine-set-role/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-engine-set-role/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-engine-unjoin/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-engine-unjoin/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-groonga/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-groonga/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-http-server-configure/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-http-server-configure/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-request/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-request/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-send/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-send/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/droonga-system-status/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/droonga-system-status/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/reference/command-line-tools/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/reference/command-line-tools/index.po 2015-11-15 23:29:56 +0900 (d442203) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /reference/\n" +"---" +msgstr "" Added: _po/ja/tutorial/add-replica/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/tutorial/add-replica/index.po 2015-11-15 23:29:56 +0900 (cc5be55) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /tutorial/\n" +"---" +msgstr "" Added: _po/ja/tutorial/dump-restore/index.po (+16 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/tutorial/dump-restore/index.po 2015-11-15 23:29:56 +0900 (cc5be55) @@ -0,0 +1,16 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-11-15 23:28+0900\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"layout: redirect-to-current-version\n" +"unversioned_path: /tutorial/\n" +"---" +msgstr "" Added: ja/reference/1.1.2/catalog/index.md (+20 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/catalog/index.md 2015-11-15 23:29:56 +0900 (77d8f99) @@ -0,0 +1,20 @@ +--- +title: カタログ +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/catalog/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +複数のリソースが集まり、Droongaネットワークを構成します。それらのリソースを **カタログ** に記述しなければいけません。ネットワーク上のすべてのノードは同じカタログを共有します。 + +カタログの指定はバージョン管理されています。利用可能なバージョンは以下のとおりです: + + * [version 2](version2/) + * [version 1](version1/): (It is deprecated since 1.0.0.) Added: ja/reference/1.1.2/catalog/version1/index.md (+303 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/catalog/version1/index.md 2015-11-15 23:29:56 +0900 (c6040f0) @@ -0,0 +1,303 @@ +--- +title: カタログ +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/catalog/version1/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +複数のリソースが集まり、Droongaネットワークを構成します。それらのリソースを **カタログ** に記述しなければいけません。ネットワーク上のすべてのノードは同じカタログを共有します。 + +このドキュメントはカタログについて説明します。 + + * TOC +{:toc} + +## 管理方法 + +今のところ、カタログを書くことも書いたカタログをすべてのノードで共有することも手動で行う必要があります。 + +近い将来、カタログを生成するユーティリティープログラムを提供する予定です。さらにその後、Droongaネットワークは自動でカタログの管理やカタログの配布を行うようになる予定です。 + +## 用語集 + +このセクションではカタログに出てくる用語を説明します。 + +### カタログ + +カタログはネットワーク内のリソースを表現するデータの集まりです。 + +### ゾーン + +ゾーンはファームの集まりです。同じゾーン内のファームはお互いに近くに配置することが期待されています。例えば、同じホスト内、同じスイッチ内、同じネットワーク内といった具合です。 + +### ファーム + +ファームはDroongaエンジンのインスタンスです。Droongaエンジンは[Fluentd][]のプラグインfluent-plugin-droongaとして実装されています。 + +1つの `fluentd` プロセスは複数のDroongaエンジンを持てます。 `fluentd.conf` に `droonga` タイプの `match` エントリーを1つ以上追加すると、 `fluentd` プロセスは同じ数のDroongaエンジンのインスタンスを生成します。 + +ファームは複数のワーカーと1つのジョブキューを持ちます。ファームはリクエストをジョブキューに投入します。ワーカーはジョブキューからリクエストを取り出します。 + +### データセット + +データセットは論理テーブルの集まりです。論理テーブルは1つのデータセットに所属しなければいけません。 + +各データセットの名前は同じDroongaネットワーク内で重複してはいけません。 + +### 論理テーブル + +論理テーブルはパーティションされた1つ以上の物理テーブルで構成されます。論理テーブルは物理レコードを持ちません。物理テーブルから物理レコードを返します。 + +1つの論理テーブルを1つ以上の物理テーブルにどうやってパーティションするかをカスタマイズできます。例えば、パーティションキーやパーテション数をカスタマイズできます。 + +### 物理テーブル + +物理テーブルはGroongaデータベースのテーブルです。Groongaのテーブルに物理レコードを保存します。 + +### リング + +リングはパーティションセットの集まりです。データセットは必ず1つのリングを持ちます。データセットはリング上に論理テーブルを作ります。 + +Droongaエンジンは物理テーブル上にあるレコードを1つ以上のパーティションセットに複製します。 + +### パーティションセット + +パーティションセットはパーティションの集まりです。1つのパーティションセットは同じDroongaネットワーク内のすべての論理テーブルのすべてのレコードを保存します。言い換えると、データセットは1つのパーティションセットの中でパーティションされます。 + +1つのパーティションセットは他のパーティションセットの複製です。 + +将来、Droongaエンジンは1つ以上のパーティションセット内でのパーティションをサポートするかもしれません。古いデータと新しいデータで異なるパーティションサイズを使うことができるので便利でしょう。通常、古いデータは小さく、新しいデータは大きくなります。大きなデータに大きなパーティションサイズを使うのは妥当なことです。 + +### パーティション + +1つのパーティションは1つのGroongaデータベースに対応します。0個以上の物理テーブルを持ちます。 + +### プラグイン + +Droonga Engine can be extended by writing plugin scripts. +In most cases, a series of plugins work cooperatively to +achieve required behaviors. +So, plugins are organized by behaviors. +Each behavior can be attached to datasets and/or tables by +adding "plugins" section to the corresponding entry in the catalog. + +More than one plugin can be assigned in a "plugins" section as an array. +The order in the array controls the execution order of plugins +when adapting messages. +When adapting an incoming message, plugins are applied in forward order +whereas those are applied in reverse order when adapting an outgoing message. + +## 例 + +Consider the following case: + + * There are two farms. + * All farms (Droonga Engine instances) works on the same fluentd. + * Each farm has two partitions. + * There are two replicas. + * There are two partitions for each table. + +Catalog is written as a JSON file. Its file name is `catalog.json`. + +Here is a `catalog.json` for the above case: + +~~~json +{ + "version": 1, + "effective_date": "2013-06-05T00:05:51Z", + "zones": ["localhost:23003/farm0", "localhost:23003/farm1"], + "farms": { + "localhost:23003/farm0": { + "device": "disk0", + "capacity": 1024 + }, + "localhost:23003/farm1": { + "device": "disk1", + "capacity": 1024 + } + }, + "datasets": { + "Wiki": { + "workers": 4, + "plugins": ["groonga", "crud", "search"], + "number_of_replicas": 2, + "number_of_partitions": 2, + "partition_key": "_key", + "date_range": "infinity", + "ring": { + "localhost:23004": { + "weight": 10, + "partitions": { + "2013-07-24": [ + "localhost:23003/farm0.000", + "localhost:23003/farm1.000" + ] + } + }, + "localhost:23005": { + "weight": 10, + "partitions": { + "2013-07-24": [ + "localhost:23003/farm1.001", + "localhost:23003/farm0.001" + ] + } + } + } + } + } +} +~~~ + +## Parameters + +Here are descriptions about parameters in `catalog.json`. + +### `version` {#version} + +It is a format version of the catalog file. + +Droonga Engine will change `catalog.json` format in the +future. Droonga Engine can provide auto format update feature with the +information. + +The value must be `1`. + +This is a required parameter. + +Example: + +~~~json +{ + "version": 1 +} +~~~ + +### `effective_date` + +It is a date string representing the day the catalog becomes +effective. + +The date string format must be [W3C-DTF][]. + +This is a required parameter. + +Note: fluent-plugin-droonga 0.8.0 doesn't use this value yet. + +Example: + +~~~json +{ + "effective_date": "2013-11-29T11:29:29Z" +} +~~~ + +### `zones` + +`Zones` is an array to express proximities between farms. +Farms are grouped by a zone, and zones can be grouped by another zone recursively. +Zones make a single tree structure, expressed by nested arrays. +Farms in a same branch are regarded as relatively closer than other farms. + +e.g. + +When the value of `zones` is as follows, + +``` +[["A", ["B", "C"]], "D"] +``` + +it expresses the following tree. + + /\ + /\ D + A /\ + B C + +This tree means the farm "B" and "C" are closer than "A" or "D" to each other. +You should make elements in a `zones` close to each other, like in the +same host, in the same switch, in the same network. + +This is an optional parameter. + +Note: fluent-plugin-droonga 0.8.0 doesn't use this value yet. + +Example: + +~~~json +{ + "zones": [ + ["localhost:23003/farm0", + "localhost:23003/farm1"], + ["localhost:23004/farm0", + "localhost:23004/farm1"] + ] +} +~~~ + +*TODO: Discuss about the call of this parameter. This seems completely equals to the list of keys of `farms`.* + +### `farms` + +It is an array of Droonga Engine instances. + +*TODO: Improve me. For example, we have to describe relations of nested farms, ex. `children`.* + +**Farms** correspond with fluent-plugin-droonga instances. A fluentd process may have multiple **farms** if more than one **match** entry with type **droonga** appear in the "fluentd.conf". +Each **farm** has its own job queue. +Each **farm** can attach to a data partition which is a part of a **dataset**. + +This is a required parameter. + +Example: + +~~~json +{ + "farms": { + "localhost:23003/farm0": { + "device": "/disk0", + "capacity": 1024 + }, + "localhost:23003/farm1": { + "device": "/disk1", + "capacity": 1024 + } + } +} +~~~ + +### `datasets` + +A **dataset** is a set of **tables** which comprise a single logical **table** virtually. +Each **dataset** must have a unique name in the network. + +### `ring` + +`ring` is a series of partitions which comprise a dataset. `replica_count`, `number_of_partitons` and **time-slice** factors affect the number of partitions in a `ring`. + +### `workers` + +`workers` is an integer number which specifies the number of worker processes to deal with the dataset. +If `0` is specified, no worker is forked and all operations are done in the master process. + +### `number_of_partitions` + +`number_of_partition` is an integer number which represents the number of partitions divided by the hash function. The hash function which determines where each record resides the partition in a dataset is compatible with memcached. + +### `date_range` + +`date_range` determines when to split the dataset. If a string "infinity" is assigned, dataset is never split by time factor. + +### `number_of_replicas` + +`number_of_replicas` represents the number of replicas of dataset maintained in the network. + + [Fluentd]: http://fluentd.org/ + [W3C-DTF]: http://www.w3.org/TR/NOTE-datetime "Date and Time Formats" Added: ja/reference/1.1.2/catalog/version2/index.md (+858 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/catalog/version2/index.md 2015-11-15 23:29:56 +0900 (8c098df) @@ -0,0 +1,858 @@ +--- +title: カタログ +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/catalog/version2/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`Catalog`はDroongaクラスタの設定を管理するためのJSONデータです。Droongaクラスタは1つ以上の`datasets`からなり、`dataset`はその他の部分からなります。それらは全て`catalog`に記述し、クラスタ内の全てホストで共有しなければなりません。 + +## 使い方 {#usage} + +この [`version`](#paramter-version) の `catalog` は Droonga 1.0.0 以降で有効です。 + +## 書式 {#syntax} + + { + "version": <Version number>, + "effectiveDate": "<Effective date>", + "datasets": { + "<Name of the dataset 1>": { + "nWorkers": <Number of workers>, + "plugins": [ + "Name of the plugin 1", + ... + ], + "schema": { + "<Name of the table 1>": { + "type" : <"Array", "Hash", "PatriciaTrie" or "DoubleArrayTrie"> + "keyType" : "<Type of the primary key>", + "tokenizer" : "<Tokenizer>", + "normalizer" : "<Normalizer>", + "columns" : { + "<Name of the column 1>": { + "type" : <"Scalar", "Vector" or "Index">, + "valueType" : "<Type of the value>", + "vectorOptions": { + "weight" : <Weight>, + }, + "indexOptions" : { + "section" : <Section>, + "weight" : <Weight>, + "position" : <Position>, + "sources" : [ + "<Name of a column to be indexed>", + ... + ] + } + }, + "<Name of the column 2>": { ... }, + ... + } + }, + "<Name of the table 2>": { ... }, + ... + }, + "fact": "<Name of the fact table>", + "replicas": [ + { + "dimension": "<Name of the dimension column>", + "slicer": "<Name of the slicer function>", + "slices": [ + { + "label": "<Label of the slice>", + "volume": { + "address": "<Address string of the volume>" + } + }, + ... + } + }, + ... + ] + }, + "<Name of the dataset 2>": { ... }, + ... + } + } + +## 詳細 {#details} + +### Catalog 定義 {#catalog} + +値 +: 以下のキーと値のペアを持つオブジェクト。 + +#### パラメータ + +##### `version` {#parameter-version} + +概要 +: カタログファイルのバージョン番号。 + +値 +: `2`. (このページに記述されている仕様はこの値が`2`のときのみ有効です) + +既定値 +: なし。これは必須のパラメータです。 + +継承可能性 +: 不可。 + +##### `effectiveDate` {#parameter-effective_date} + +概要 +: このカタログが有効になる時刻。 + +値 +: [W3C-DTF](http://www.w3.org/TR/NOTE-datetime "Date and Time Formats") でフォーマットされたタイムゾーン付きの時刻。 + +既定値 +: なし。これは必須のパラメータです。 + +継承可能性 +: 不可。 + +##### `datasets` {#parameter-datasets} + +概要 +: データセットの定義。 + +: データセット名をキーとし、[`dataset` 定義](#dataset) を値とするオブジェクト。 + +既定値 +: なし。これは必須のパラメータです。 + +継承可能性 +: 不可。 + +##### `nWorkers` {#parameter-n_workers} + +概要 +: データベースインスタンス毎にspawnされるワーカの数。 + +値 +: 整数。 + +既定値 +: 0 (ワーカー無し。全ての処理がマスタープロセス内で行われます) + +継承可能性 +: 可。`dataset`と`volume`の定義でオーバライドできます。 + + +#### 例 + +A version 2 catalog effective after `2013-09-01T00:00:00Z`, with no datasets: + +~~~ +{ + "version": 2, + "effectiveDate": "2013-09-01T00:00:00Z", + "datasets": { + } +} +~~~ + +### Dataset 定義 {#dataset} + +値 +: 以下のキーと値のペアを持つオブジェクト。 + +#### パラメータ + +##### `plugins` {#parameter-plugins} + +概要 +: このデータセットにおいて有効にするプラグイン名文字列の配列。 + +値 +: 文字列の配列。 + +既定値 +: なし。これは必須のパラメータです。 + +継承可能性 +: 可。`dataset`と`volume`の定義でオーバライドできます。 + +##### `schema` {#parameter-schema} + +概要 +: テーブルとそのカラムの定義。 + +値 +: テーブル名をキーとし、[`table` 定義](#table)を値とするオブジェクト。 + +既定値 +: なし。これは必須のパラメータです。 + +継承可能性 +: 可。`dataset`と`volume`の定義でオーバライドできます。 + +##### `fact` {#parameter-fact} + +概要 +: fact テーブルの名前。`dataset`が複数の`slice`に格納される場合、[`schema`](#parameter-schema)パラメータで定義されたテーブルの中から、1つ[fact table](http://en.wikipedia.org/wiki/Fact_table)を選択する必要があります。 + +値 +: 文字列。 + +既定値 +: なし。 + +継承可能性 +: 可。`dataset`と`volume`の定義でオーバライドできます。 + +##### `replicas` {#parameter-replicas} + +概要 +: 互いに複製されるボリュームの集合。 + +値 +: [`volume` 定義](#volume)の配列。 + +既定値 +: なし。これは必須のパラメータです。 + +継承可能性 +: 不可。 + +#### 例 + +データベースインスタンスに1つにつき4ワーカーを持ち、プラグイン`groonga`、`crud`、`search`を使用するデータセット: + +~~~ +{ + "nWorkers": 4, + "plugins": ["groonga", "crud", "search"], + "schema": { + }, + "replicas": [ + ] +} +~~~ + +### Table 定義 {#table} + +値 +: 以下のキーと値のペアを持つオブジェクト。 + +#### パラメータ + +##### `type` {#parameter-table-type} + +概要 +: テーブルのキーを管理するためのデータ構造を指定する。 + +値 +: 以下のうちいずれかの値。 + +* `"Array"`: キーの無いテーブル +* `"Hash"`: ハッシュテーブル +* `"PatriciaTrie"`: パトリシアトライテーブル +* `"DoubleArrayTrie"`: ダブル配列トライテーブル + +既定値 +: `"Hash"` + +継承可能性 +: 不可。 + +##### `keyType` {#parameter-keyType} + +概要 +: テーブルにおけるキーのデータ型。`type`が`"Array"`の場合は指定してはいけません。 + +値 +: 以下のデータ型のうちのいずれか。 + +* `"Integer"` : 64bit 符号付き整数。 +* `"Float"` : 64bit 浮動小数点数。 +* `"Time"` : マイクロ秒精度の時刻。 +* `"ShortText"` : 4095バイトまでの文字列。 +* `"TokyoGeoPoint"` : 旧日本測地系による経緯度。 +* `"WGS84GeoPoint"` : [WGS84](http://en.wikipedia.org/wiki/World_Geodetic_System) による経緯度。 + +既定値 +: なし。キーを持つテーブルでは指定が必須です。 + +継承可能性 +: 不可。 + +##### `tokenizer` {#parameter-tokenizer} + +概要 +: 語彙表として使われるテーブルにおける、文字列型の値を分割するために使うトークナイザーの種類を指定します。`keyType`が`"ShortText"`である場合にのみ有効です。 + +値 +: 以下のトークナイザー名のうちのいずれか。 + +* `"TokenDelimit"` +* `"TokenUnigram"` +* `"TokenBigram"` +* `"TokenTrigram"` +* `"TokenBigramSplitSymbol"` +* `"TokenBigramSplitSymbolAlpha"` +* `"TokenBigramSplitSymbolAlphaDigit"` +* `"TokenBigramIgnoreBlank"` +* `"TokenBigramIgnoreBlankSplitSymbol"` +* `"TokenBigramIgnoreBlankSplitSymbolAlpha"` +* `"TokenBigramIgnoreBlankSplitSymbolAlphaDigit"` +* `"TokenDelimitNull"` + +既定値 +: なし。 + +継承可能性 +: 不可。 + +##### `normalizer` {#parameter-normalizer} + +概要 +: キーの値を正規化・制限するノーマライザーの種類を指定します。`keyType`が`"ShortText"`である場合にのみ有効です。 + +値 +: 以下のノーマライザー名のうちのいずれか。 + +* `"NormalizerAuto"` +* `"NormalizerNFKC51"` + +既定値 +: なし。 + +継承可能性 +: 不可。 + +##### `columns` {#parameter-columns} + +概要 +: テーブルのカラムの定義。 + +Value +: An object keyed by the name of the column with value the [`column` definition](#column). + +既定値 +: なし。 + +継承可能性 +: 不可。 + +#### 例 + +##### 例1: Hashテーブル + +`ShortText`型のキーを持つ`Hash`テーブルで、カラムは無いもの: + +~~~ +{ + "type": "Hash", + "keyType": "ShortText", + "columns": { + } +} +~~~ + +##### 例2: PatriciaTrieテーブル + +`TokenBigram`トークナイザと`NormalizerAuto`ノーマライザを利用する`PatriciaTrie`テーブル + +~~~ +{ + "type": "PatriciaTrie", + "keyType": "ShortText", + "tokenizer": "TokenBigram", + "normalizer": "NormalizerAuto", + "columns": { + } +} +~~~ + +### Column 定義 {#column} + +値 + +: An object with the following key/value pairs. + +#### パラメータ + +##### `type` {#parameter-column-type} + +Abstract +: Specifies the quantity of data stored as each column value. + +Value +: Any of the followings. + +* `"Scalar"`: A single value. +* `"Vector"`: A list of values. +* `"Index"` : A set of unique values with additional properties respectively. Properties can be specified in [`indexOptions`](#parameter-indexOptions). + +Default value +: `"Scalar"` + +継承可能性 +: 不可。 + +##### `valueType` {#parameter-valueType} + +Abstract +: Data type of the column value. + +Value +: Any of the following data types or the name of another table defined in the same dataset. When a table name is assigned, the column acts as a foreign key references the table. + +* `"Bool"` : `true` or `false`. +* `"Integer"` : 64bit signed integer. +* `"Float"` : 64bit floating-point number. +* `"Time"` : Time value with microseconds resolution. +* `"ShortText"` : Text value up to 4,095 bytes length. +* `"Text"` : Text value up to 2,147,483,647 bytes length. +* `"TokyoGeoPoint"` : Tokyo Datum based geometric point value. +* `"WGS84GeoPoint"` : [WGS84](http://en.wikipedia.org/wiki/World_Geodetic_System) based geometric point value. + +既定値 +: なし。これは必須のパラメータです。 + +継承可能性 +: 不可。 + +##### `vectorOptions` {#parameter-vectorOptions} + +概要 +: データベースインスタンスの場所を指定します。 + +Value +: An object which is a [`vectorOptions` definition](#vectorOptions) + +Default value +: `{}` (Void object). + +継承可能性 +: 不可。 + +##### `indexOptions` {#parameter-indexOptions} + +概要 +: データベースインスタンスの場所を指定します。 + +Value +: An object which is an [`indexOptions` definition](#indexOptions) + +Default value +: `{}` (Void object). + +継承可能性 +: 不可。 + +#### 例 + +##### 例1: スカラー型カラム + +`ShortText`を格納するスカラー型のカラム: + +~~~ +{ + "type": "Scalar", + "valueType": "ShortText" +} +~~~ + +##### 例2: ベクター型カラム + +A vector column to store `ShortText` values with weight: + +~~~ +{ + "type": "Scalar", + "valueType": "ShortText", + "vectorOptions": { + "weight": true + } +} +~~~ + +##### 例3: インデックスカラム + +`Store`テーブルの`address`カラムをインデックスするカラム: + +~~~ +{ + "type": "Index", + "valueType": "Store", + "indexOptions": { + "sources": [ + "address" + ] + } +} +~~~ + +### vectorOptions 定義 {#vectorOptions} + +値 +: 以下のキーと値のペアを持つオブジェクト。 + +#### パラメータ + +##### `weight` {#parameter-vectorOptions-weight} + +Abstract +: Specifies whether the vector column stores the weight data or not. Weight data is used for indicating the importance of the value. + +Value +: A boolean value (`true` or `false`). + +Default value +: `false`. + +継承可能性 +: 不可。 + +#### 例 + +Store the weight data. + +~~~ +{ + "weight": true +} +~~~ + +### indexOptions 定義 {#indexOptions} + +値 +: 以下のキーと値のペアを持つオブジェクト。 + +#### パラメータ + +##### `section` {#parameter-indexOptions-section} + +Abstract +: Specifies whether the index column stores the section data or not. Section data is typically used for distinguishing in which part of the sources the value appears. + +Value +: A boolean value (`true` or `false`). + +Default value +: `false`. + +継承可能性 +: 不可。 + +##### `weight` {#parameter-indexOptions-weight} + +Abstract +: Specifies whether the index column stores the weight data or not. Weight data is used for indicating the importance of the value in the sources. + +Value +: A boolean value (`true` or `false`). + +Default value +: `false`. + +継承可能性 +: 不可。 + +##### `position` {#parameter-indexOptions-position} + +Abstract +: Specifies whether the index column stores the position data or not. Position data is used for specifying the position where the value appears in the sources. It is indispensable for fast and accurate phrase-search. + +Value +: A boolean value (`true` or `false`). + +Default value +: `false`. + +継承可能性 +: 不可。 + +##### `sources` {#parameter-indexOptions-sources} + +Abstract +: Makes the column an inverted index of the referencing table's columns. + +Value +: An array of column names of the referencing table assigned as [`valueType`](#parameter-valueType). + +既定値 +: なし。 + +継承可能性 +: 不可。 + +#### 例 + +Store the section data, the weight data and the position data. +Index `name` and `address` on the referencing table. + +~~~ +{ + "section": true, + "weight": true, + "position": true + "sources": [ + "name", + "address" + ] +} +~~~ + +### Volume 定義 {#volume} + +概要 +: データセットを構成する単位。データセットは1つ、もしくは複数のボリュームからなります。ボリュームは単一のデータベースインスタンスか、`slices` の集合で構成されます。ボリュームが単一のデータベースインスタンスから構成される場合は、`address`パラメータを指定しなければなりません。このとき、それ以外のパラメータを指定してはいけません。そうでない場合は、`dimension`と`slicer`と`slices`が必須で、他は指定してはいけません。 + +値 +: 以下のキーと値のペアを持つオブジェクト。 + +#### パラメータ + +##### `address` {#parameter-address} + +概要 +: データベースインスタンスの場所を指定します。 + +値 +: 以下の書式の文字列。 + + ${host_name}:${port_number}/${tag}.${name} + + * `host_name`: データベースのインスタンスを保持するホストの名前。 + * `port_number`: データベースのインスタンスのためのポート番号。 + * `tag`: データベースのインスタンスのタグ名。タグ名には`.`を含めることはできません。ホスト名とポート番号のペアごとに、複数のタグを使うことができます。 + * `name`: データベースのインスタンスの名前。あるホスト名・ポート番号・タグ名の3つの組み合わせごとに、複数のインスタンス名を使うことができます。 + +既定値 +: なし。 + +継承可能性 +: 不可。 + +##### `dimension` {#parameter-dimension} + +概要 +: fact表の中でレコードをスライスする次元を指定します。fact表の'_key'または[`columns`](#parameter-columns)からスカラー型のカラムを選択します。[dimension](http://en.wikipedia.org/wiki/Dimension_%28data_warehouse%29)を参照してください。 + +値 +: 文字列。 + +既定値 +: `"_key"` + +継承可能性 +: 可。`dataset`と`volume`の定義でオーバライドできます。 + +##### `slicer` {#parameter-slicer} + +概要 +: dimensionカラムをsliceする関数。 + +値 +: スライサー関数の名前。 + +既定値 +: `"hash"` + +継承可能性 +: 可。`dataset`と`volume`の定義でオーバライドできます。 + +`slices`の集合からなるボリュームを定義するためには、レコードを複数のスライスに振り分けるための方法を決める必要があります。 + +`slice`で指定されたスライサー関数と、スライサー関数への入力として与えられる`dimension`で指定されたカラム(またはキー)によって、それが決まります。 + +スライサーは以下の3種類に分けられます: + +比例尺度 +: *比例尺度スライサー*は、個々のデータを指定された比率で、_keyのハッシュ値などに基づいて振り分けます。 + この種類のスライサー: + + * `hash` + +順序尺度 +: *順序尺度スライサー*は、個々のデータを順序のある値(時間、整数、`{High, Middle, Low}`など)に基づいて振り分けます。 + この種類のスライサー: + + * (未実装) + +名義尺度 +: *名義尺度スライサー*は、個々のデータをカテゴリを示す名義(国名、郵便番号、色など)で振り分けます。 + この種類のスライサー: + + * (未実装) + +##### `slices` {#parameter-slices} + +概要 +: データを格納するスライスの定義。 + +値 +: [`slice` 定義](#slice)の配列。 + +既定値 +: なし。 + +継承可能性 +: 不可。 + +#### 例 + +##### 例1: 単一のインスタンス + +"localhost:24224/volume.000"にあるボリューム: + +~~~ +{ + "address": "localhost:24224/volume.000" +} +~~~ + +##### Example 2: 複数のスライス + +3つのスライスから構成され、`_key`に対してratio-scaledなスライサー関数`hash`を適用してレコードを分散させるボリューム + +~~~ +{ + "dimension": "_key", + "slicer": "hash", + "slices": [ + { + "volume": { + "address": "localhost:24224/volume.000" + } + }, + { + "volume": { + "address": "localhost:24224/volume.001" + } + }, + { + "volume": { + "address": "localhost:24224/volume.002" + } + } + ] +~~~ + +### Slice 定義 {#slice} + +概要 +: スライスの定義。スライスされたデータの範囲と、それを保存するボリュームを指定する。 + +値 +: 以下のキーと値のペアを持つオブジェクト。 + +#### パラメータ + +##### `weight` {#parameter-slice-weight} + +概要 +: スライス内での割り当て量を指定します。`slicer`が atio-scaledの場合のみ有効。 + +値 +: 数値。 + +既定値 +: `1` + +継承可能性 +: 不可。 + +##### `label` {#parameter-label} + +概要 +: slicer が返す具体的な値。 slicerがnominal-scaledの場合のみ有効。 + +Value +: A value of the dimension column data type. When the value is not provided, this slice is regarded as *else*; matched only if all other labels are not matched. Therefore, only one slice without `label` is allowed in slices. + +既定値 +: なし。 + +継承可能性 +: 不可。 + +##### `boundary` {#parameter-boundary} + +概要 +: `slicer`の返す値と比較可能な具体的な値。`slicer`がordinal-scaledの場合のみ有効。 + +Value +: A value of the dimension column data type. When the value is not provided, this slice is regarded as *else*; this means the slice is open-ended. Therefore, only one slice without `boundary` is allowed in a slices. + +既定値 +: なし。 + +継承可能性 +: 不可。 + +##### `volume` {#parameter-volume} + +概要 +: スライスに対応するデータを格納するボリューム。 + +値 + +: [`volume` 定義](#volume)オブジェクト + +既定値 +: なし。 + +継承可能性 +: 不可。 + +#### 例 + +##### 例1: Ratio-scaled + +ratio-scaledなスライサーのためのスライス、重みは`1` + +~~~ +{ + "weight": 1, + "volume": { + } +} +~~~ + +##### 例2: Nominal-scaled + +nominal-scaledなスライサーのためのスライス、ラベルは `"1"` + +~~~ +{ + "label": "1", + "volume": { + } +} +~~~ + +##### 例3: Ordinal-scaled + +ordinal-scaledなスライサーに対するスライス、境界値は`100`: + +~~~ +{ + "boundary": 100, + "volume": { + } +} +~~~ + +## 実際の例 + +[基本的な使い方のチュートリアル][basic tutorial]に登場するカタログを参照してください。 + + [basic tutorial]: ../../../tutorial/basic Added: ja/reference/1.1.2/command-line-tools/drndump/index.md (+107 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/drndump/index.md 2015-11-15 23:29:56 +0900 (e1539d1) @@ -0,0 +1,107 @@ +--- +title: drndump +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/drndump/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`drndump`は、指定されたDroongaクラスタ内の特定のデータセットについて、全てのスキーマ定義、レコード、およびインデックスの定義を抽出します。 + +例えば、`192.168.100.50`というDroonga Engineノードがあり、同一ネットワークセグメント内のコンピュータ`192.168.100.10`にログインしている場合、クラスタ内の全てのデータを抽出するコマンド列は以下のようになります: + +~~~ +(on 192.168.100.10) +$ drndump --host 192.168.100.50 --receiver-host 192.168.100.10 +{ + "type": "table_create", + "dataset": "Default", + "body": { + "name": "Location", + "flags": "TABLE_PAT_KEY", + "key_type": "WGS84GeoPoint" + } +} +{ + "type": "table_create", + "dataset": "Default", + "body": { + "name": "Store", + "flags": "TABLE_PAT_KEY", + "key_type": "ShortText" + } +} +... +{ + "type": "column_create", + "dataset": "Default", + "body": { + "table": "Term", + "name": "store_name", + "type": "Store", + "flags": "COLUMN_INDEX|WITH_POSITION", + "source": "name" + } +} +~~~ + +このコマンドの出力は、別のDroongaクラスタに同じデータを復元することのできる妥当なメッセージの一覧です。 +言い換えると、このコマンドはあるDroongaクラスタの完全なバックアップを作成することができます。 + +出力はリダイレクトを使って以下のようにファイルに保存できます: + +~~~ +(on 192.168.100.10) +$ drndump --host 192.168.100.50 --receiver-host 192.168.100.10 \ + > dump.jsons +~~~ + +[`droonga-request`コマンド](../droonga-request/)または[`droonga-send`コマンド](../droonga-send/)を使うと、ダンプ出力からデータセットを復元できます。 +各コマンドの説明も参照して下さい。 + + +## パラメータ {#parameters} + +`--host=NAME` +: メッセージの送信先となるEngineノードのホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--port=PORT` +: Engineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: Engineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + +`--dataset=NAME` +: ダンプ出力するデータセットの名前。 + 既定値は`Default`です。 + +`--receiver-host=NAME` +: このコマンドを実行しているコンピュータのホスト名。 + 既定値は、そのコンピュータのホスト名として推測される名前です。 + +`--help` +: コマンドの使い方の説明を表示します。 + + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`drndump`の一部としてインストールされます。 + +~~~ +# gem install drndump +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-add/index.md (+137 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-add/index.md 2015-11-15 23:29:56 +0900 (1ea8b1b) @@ -0,0 +1,137 @@ +--- +title: droonga-add +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-add/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-add`は、Droongaクラスタ内の指定されたテーブルについて、新しいレコードの追加および既存レコードの更新を行います。 + +例えば、`192.168.100.50`というDroonga Engineノードがあり、同一ネットワークセグメント内のコンピュータ`192.168.100.10`にログインしている場合、クラスタ内の`User`テーブルにレコードを1つ追加するコマンド列は以下のようになります: + +~~~ +(on 192.168.100.10) +$ droonga-add --host 192.168.100.50 --receiver-host 192.168.100.10 \ + --table User --key id1 --name Adam --age 20 +Adding new record... +{ + "table": "Store", + "key": "id1", + "values": { + "name": "Adam", + "age": "20" + } +} +Done. +~~~ + +このコマンドは、typeが[`add`](../../commands/add/)であるメッセージを[`droonga-request`](../droonga-request/)を用いて送信する操作を簡単に行う物です。 +上記コマンド列によってもたらされる結果は、以下のコマンド列の結果と実質的に同一です: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"add","body":{"key":"id1","values":{"name":"Adam","age":20}}}' | + droonga-request --report-request --host 192.168.100.50 --receiver-host 192.168.100.10 +Request: { + "type": "add", + "body": { + "table": "Store", + "key": "id1", + "values": { + "name": "Adam", + "age": "20" + } + }, + "id": "1430961788.4171028", + "date": "2015-05-07T02:39:50.334377Z", + "dataset": "Default" +} +Elapsed time: 0.023309135 +{ + "inReplyTo": "1430961788.4171028", + "statusCode": 200, + "type": "add.result", + "body": true +} +~~~ + +[`add`コマンドのリファレンス](../../commands/add/)も併せて参照して下さい。 + +## パラメータ {#parameters} + +`--table=TABLE` *(必須)* +: レコードを追加するテーブルの名前。 + +`--key=KEY` +: 追加または更新するレコードの一意なキー。 + +`--(COLUMN NAME)=(VALUE)`, `--value:(COLUMN NAME)=(VALUE)` +: レコードのカラムの値。 + `host`のように既存の他のパラメータと同じ名前のカラムの値を指定する場合は、`--value:`という接頭辞を付ける必要があります。 + +`--host=NAME` +: メッセージの送信先となるEngineノードのホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--port=PORT` +: Engineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: Engineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + +`--dataset=NAME` +: メッセージの送信先データセット名。 + 既定値は`Default`です。 + +`--receiver-host=NAME` +: このコマンドを実行しているコンピュータのホスト名。 + 既定値は、そのコンピュータのホスト名として推測される名前です。 + +`--target-role=ROLE` +: メッセージを処理できるEngineノードのロール。 + 以下のいずれかを指定します: + + * `service-provider`: + メッセージは、クラスタ内でサービスを提供中のノードで処理されます。 + データ抽出操作に関わるノードには、後から遅れてメッセージが伝搬します。 + * `absorb-source`: + メッセージは、クラスタへのノード追加操作におけるデータコピー元となっているノードで処理されます。 + サービスを提供中のノード、並びにデータコピー先となっているノードへは、メッセージは伝搬しません。 + * `absorb-destination`: + メッセージは、クラスタへのノード追加操作におけるデータコピー先となっているノードで処理されます。 + サービスを提供中のノード、並びにデータコピー元となっているノードへは、メッセージは伝搬しません。 + * `any`: + メッセージは、`--host`で指定されたノードで処理されます。 + + 既定値は`any`です。 + +`--timeout=SECONDS` +: 応答がない接続を打ち切るまでの待ち時間(単位:秒)です。 + 既定値は`3`です。 + +`-h`, `--help` +: コマンドの使い方の説明を表示します。 + + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-client`の一部としてインストールされます。 + +~~~ +# gem install droonga-client +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-engine-absorb-data/index.md (+121 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-engine-absorb-data/index.md 2015-11-15 23:29:56 +0900 (6d9b7e6) @@ -0,0 +1,121 @@ +--- +title: droonga-engine-absorb-data +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-engine-absorb-data/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-engine-absorb-data`は、指定されたコピー元データセットからコピー先データセットへ全てのデータをコピーします。 + +例えば、`192.168.100.50`というコピー元クラスタのDroonga Engineノードがあり、コピー先の別クラスタのDroonga Engineノードである`192.168.200.10`にログインしている場合、`192.168.100.50`から`192.168.200.10`へ全てのデータをコピーするコマンド列は以下のようになります: + +~~~ +(on 192.168.200.10) +$ droonga-engine-absorb-data --host 192.168.200.10 \ + --receiver-host 192.168.200.10 \ + --source-host 192.168.100.50 +Start to absorb data from Defau****@192*****:10031/droonga + to Defau****@192*****:10031/droonga + via 192.168.200.10 (this host) + +Absorbing... +Getting the timestamp of the last processed message in the source node... +The timestamp of the last processed message in the source node: 2015-04-29T10:07:08.230158Z +Setting the destination node to ignore messages older than the timestamp... +100% done (maybe 00:00:00 remaining) +Done. +~~~ + +このコマンドは1つのDroongaクラスタ内であるデータセットから別のデータセットへデータをコピーする事もできます。 +例えば、以下はマスターとなる既存のデータセットの内容を別のテスト用データセットへコピーするコマンド列です: + +~~~ +(on 192.168.100.50) +$ droonga-engine-absorb-data --receiver-host 192.168.100.50 \ + --host 192.168.100.50 \ + --dataset Testing \ + --source-host 192.168.100.50 \ + --source-dataset Default +Start to absorb data from Defau****@192*****:10031/droonga + to Testi****@192*****:10031/droonga + via 192.168.100.50 (this host) +... +~~~ + +[複数のDroongaクラスタ間でのデータのコピーについてのチュートリアル](/ja/tutorial/dump-restore/)も併せて参照して下さい。 + + +## パラメータ {#parameters} + +`--host=NAME` +: データのコピー先となるEngineノードのホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--port=PORT` +: データのコピー先となるEngineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: データのコピー先となるEngineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + +`--dataset=NAME` +: データのコピー先となるデータセットの名前。 + 既定値は`Default`です。 + +`--source-host=NAME` +: データのコピー元となるEngineノードのホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--source-port=PORT` +: データのコピー元となるEngineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + +`--source-tag=TAG` +: データのコピー元となるEngineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + +`--source-dataset=NAME` +: データのコピー元となるデータセットの名前。 + 既定値は`Default`です。 + +`--receiver-host=NAME` +: このコマンドを実行しているコンピュータのホスト名。 + 既定値は、そのコンピュータのホスト名として推測される名前です。 + +`--records-per-second=N` +: 1秒間にコピーするレコードの最大数。 + `-1`を指定した場合、"無制限"を意味します。 + 既定値は`100`です。 + +`--progress-interval-seconds=SECONDS` +: データコピーの進捗を報告する間隔の秒数。 + 既定値は`3`です。 + +`--[no-]verbose` +: 内部的な操作の詳細を出力するかどうか。 + 主にデバッグ用のオプションです。 + +`--help` +: コマンドの使い方の説明を表示します。 + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-engine`の一部としてインストールされます。 + +~~~ +# gem install droonga-engine +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-generate/index.md (+363 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-generate/index.md 2015-11-15 23:29:56 +0900 (1f4b4d8) @@ -0,0 +1,363 @@ +--- +title: droonga-engine-catalog-generate +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-generate/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-engine-catalog-generate`は、Droonga Engineノード用の新しい[`catalog.json`ファイル](../../catalog/version2/)を生成します。 + +多くの場合において、このコマンドを使う必要はまずありません。代わりに、Engineノードの初期化には[`droonga-engine-configure`コマンド](../droonga-engine-configure/)を使い、クラスタ構成の変更には[`droonga-engine-join`](../droonga-engine-join/)や[`droonga-engine-unjoin`](../droonga-engine-unjoin/)のような管理コマンドを使って下さい。 + +このコマンドは、新しい`catalog.json`をゼロから生成する事に特化して設計されています。 +replicaノードのリストだけを変更したい場合には、[`droonga-engine-catalog-modify`コマンド](../droonga-engine-catalog-modify/)の方が便利です。 + +## 例 {#examples} + +### 1つだけのボリュームを持つ孤立したクラスタ + +最も一般的な使い方は、[`droonga-engine-join`コマンド](../droonga-engine-join/)によって管理される新しいレプリカノードとして、孤立したEngineノード用の`catalog.json`を生成する場面です。例えば、まだ準備されていないノードである`192.168.100.50`にログインしている場合のコマンド列は以下の通りです: + +~~~ +(on 192.168.100.50) +# droonga-engine-catalog-generate --hosts 192.168.100.50 +~~~ + +省略されたオプションを含めた完全な指定はこのようになります: + +~~~ +(on 192.168.100.50) +# droonga-engine-catalog-generate \ + --output /home/droonga-engine/droonga/catalog.json \ + --dataset Default \ + --n-workers 4 \ + --hosts 192.168.100.50 \ + --port 10031 \ + --tag droonga \ + --n-slices 1 \ + --plugins groonga,search,crud,dump,system,catalog +~~~ + +`--n-workers`、`--hosts`、`--port`、`--tag`、`--n-slices`および`--plugins`の各オプションは、最も近くに書かれた先行する`--dataset`オプションに紐付けられています。 +ユーザが指定した`--dataset`オプションよりも前に書かれたこれらのオプションの指定は、自動的に既定のデータセット名`Default`に対して紐付けられます。 + +生成された`catalog.json`の例は以下の通りです: + +~~~ +{ + "version": 2, + "effectiveDate": "2015-05-08T09:02:12+00:00", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.50:10031/droonga.000" } } + ] + } + ] + } + } +} +~~~ + + +### 複数のreplicaノードを含むクラスタ + +複数のreplicaノードを持つデータセットを定義するには、replicaノードとして使われる全てのノードのホスト名を`,`(カンマ)で区切って`--host`オプションに指定します: + +~~~ +(on 192.168.100.50) +# droonga-engine-catalog-generate \ + --hosts 192.168.100.50,192.168.100.51 +~~~ + +省略されたオプションを含めた完全な指定はこのようになります: + +~~~ +(on 192.168.100.50) +# droonga-engine-catalog-generate \ + --output /home/droonga-engine/droonga/catalog.json \ + --dataset Default \ + --n-workers 4 \ + --hosts 192.168.100.50,192.168.100.51 \ + --port 10031 \ + --tag droonga \ + --n-slices 1 \ + --plugins groonga,search,crud,dump,system,catalog +~~~ + +生成された`catalog.json`の例は以下の通りです: + +~~~ +{ + "version": 2, + "effectiveDate": "2015-05-08T09:02:12+00:00", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.50:10031/droonga.000" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.51:10031/droonga.000" } } + ] + } + ] + } + } +} +~~~ + + +### 複数のreplicaノードと、それぞれのreplicaについて複数のsliceを含むクラスタ + +sliceに分割されたreplicaを持つデータセットを定義するためには、`--n-slices`オプションをそのデータセットに対して指定する必要があります: + +~~~ +(on 192.168.100.50) +# droonga-engine-catalog-generate \ + --hosts 192.168.100.50,192.168.100.51 \ + --n-slices 2 +~~~ + +省略されたオプションを含めた完全な指定はこのようになります: + +~~~ +(on 192.168.100.50) +# droonga-engine-catalog-generate \ + --output /home/droonga-engine/droonga/catalog.json \ + --dataset Default \ + --n-workers 4 \ + --hosts 192.168.100.50,192.168.100.51 \ + --port 10031 \ + --tag droonga \ + --n-slices 2 \ + --plugins groonga,search,crud,dump,system,catalog +~~~ + +生成された`catalog.json`の例は以下の通りです: + +~~~ +{ + "version": 2, + "effectiveDate": "2015-05-08T09:02:12+00:00", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 50, + "volume": { "address": "192.168.100.50:10031/droonga.000" } }, + { "weight": 50, + "volume": { "address": "192.168.100.50:10031/droonga.001" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 50, + "volume": { "address": "192.168.100.51:10031/droonga.000" } }, + { "weight": 50, + "volume": { "address": "192.168.100.51:10031/droonga.001" } } + ] + } + ] + } + } +} +~~~ + +`2`またはそれより大きな数を`--n-slices`オプションで指定すると、複数のsliceが各replicaノード自身の上に生成されます。 +有効なslice分けのためには1つのsliceごとに1ノードを割り当てるべきですが、現在のところこのコマンドはそのようなパターンに対応していません。 +また、slice配下のreplicaの定義にもまだ対応できていません。 +これらの制限事項は将来のバージョンで解消される予定です。 + +### 2つ以上のデータセットを含むクラスタ + +クラスタ内に複数のデータセットを定義するには、`--dataset`オプションを使う必要があります: + +~~~ +(on 192.168.100.50) +# droonga-engine-catalog-generate \ + --hosts 192.168.100.50,192.168.100.51 \ + --port 20031 \ + --dataset Testing \ + --hosts 192.168.100.60,192.168.100.61 \ + --port 20032 +~~~ + +省略されたオプションを含めた完全な指定はこのようになります: + +~~~ +(on 192.168.100.50) +# droonga-engine-catalog-generate \ + --output /home/droonga-engine/droonga/catalog.json \ + --dataset Default \ + --n-workers 4 \ + --hosts 192.168.100.50,192.168.100.51 \ + --port 20031 \ + --tag droonga \ + --n-slices 1 \ + --plugins groonga,search,crud,dump,system,catalog \ + --dataset Testing \ + --n-workers 4 \ + --hosts 192.168.100.60,192.168.100.61 \ + --port 20032 \ + --tag droonga \ + --n-slices 1 \ + --plugins groonga,search,crud,dump,system,catalog +~~~ + +上記の例の通り、データセットに紐付けられたオプションはそれに先行する最も近くに書かれた`--dataset`オプションで定義されるデータセットに対して影響を及ぼします。 + +生成された`catalog.json`の例は以下の通りです: + +~~~ +{ + "version": 2, + "effectiveDate": "2015-05-08T09:02:12+00:00", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.50:20031/droonga.000" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.51:20031/droonga.000" } } + ] + } + ] + }, + "Testing": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.60:20032/droonga.000" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.61:20032/droonga.000" } } + ] + } + ] + } + } +} +~~~ + + +## パラメータ {#parameters} + +`--output=PATH` +: 生成された`catalog.json`の保存先パス。 + `-`を指定した場合は標準出力に対して出力します。 + 指定されたパスの位置にある既存のファイルは、確認無しに上書きされます。 + 既定値は、そのコンピュータ上に設定される`droonga-engine`サービスの`catalog.json`の位置(`/home/droonga-engine/droonga/catalog.json`)です。 + +`--dataset=NAME` +: 新たに定義するデータセットの名前。 + 複数のデータセットを定義できるように、このオプションは複数回指定できます。 + 既定値は`Default`です。 + +`--n-workers=N` +: 先行する`--dataset`オプションで定義されたデータセットにおいて、個々のvolumeに対して用意するworkerの数。 + 既定値は`4`です。 + +`--hosts=NAME1,NAME2,...` +: 先行する`--dataset`オプションで定義されたデータセットにおいて、replicaとして使う1つ以上のEngineノードのホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--port=PORT` +: 先行する`--dataset`オプションで定義されたデータセットにおいて、Engineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: 先行する`--dataset`オプションで定義されたデータセットにおいて、Engineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + +`--n-slices=N` +: 先行する`--dataset`オプションで定義されたデータセットにおいて、各レプリカに用意するsliceの数。 + 既定値は`1`です。 + +`--plugins=PLUGIN1,PLUGIN2,...` +: 先行する`--dataset`オプションで定義されたデータセットにおいて、有効化するプラグインの名前。 + 既定値は`groonga,search,crud,dump,system,catalog`(組み込みのプラグイン全ての一覧)です。 + +`--schema=PATH` +: 先行する`--dataset`オプションで定義されたデータセット向けのスキーマ定義を含んだJSONファイルのパス。 + +`--fact=TABLE` +: 先行する`--dataset`オプションで定義されたデータセットにおいて、fact表として扱うtableの名前。 + +`--replicas=PATH` +: 先行する`--dataset`オプションで定義されたデータセット向けのreplica群の定義を含んだJSONファイルのパス。 + このオプションが指定された場合、データセット内にreplica群を定義するための他のオプション(`--hosts`、`--port`、`--tag`、および`--n-slices`)は全て無視されます。 + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-engine`の一部としてインストールされます。 + + +~~~ +# gem install droonga-engine +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-modify/index.md (+474 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-modify/index.md 2015-11-15 23:29:56 +0900 (dc87d76) @@ -0,0 +1,474 @@ +--- +title: droonga-engine-catalog-modify +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-engine-catalog-modify/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-engine-catalog-modify`は、既存の`catalog.json`を変更してDroongaクラスタの構成を変えます。 + +多くの場合において、このコマンドを使う必要はまずありません。代わりに、クラスタ構成の変更には[`droonga-engine-join`](../droonga-engine-join/)や[`droonga-engine-unjoin`](../droonga-engine-unjoin/)のような管理コマンドを使って下さい。 + +## 例 {#examples} + +例えば、`/tmp/catalog.json`の位置に以下のような内容の`catalog.json`があるとします: + +~~~ +{ + "version": 2, + "effectiveDate": "2015-05-08T09:02:12+00:00", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.50:10031/droonga.000" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.51:10031/droonga.000" } } + ] + } + ] + }, + "Testing": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.60:20031/droonga.000" } } + ] + } + ] + } + } +} +~~~ + +### 新しいreplicaの追加 + +クラスタ内のデータセット`Default`に新しいreplicaノード`192.168.100.52`を加えるコマンド列は以下の通りです: + +~~~ +$ droonga-engine-catalog-modify \ + --source /tmp/catalog.json \ + --no-update \ + --add-replica-hosts 192.168.100.52 +~~~ + +省略されたオプションを含めた完全な指定はこのようになります: + +~~~ +$ droonga-engine-catalog-modify \ + --source /tmp/catalog.json \ + --output - \ + --no-update \ + --dataset Default \ + --add-replica-hosts 192.168.100.52 +~~~ + +このコマンドは既存の他のreplicaと同じポート番号とタグ名を自動的に適用します。 +それらの情報を指定する必要はありません。 + +変更された`catalog.json`は以下の通りです: + +~~~ +{ + "version": 2, + "effectiveDate": "2015-05-08T09:02:12+00:00", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.50:10031/droonga.000" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.51:10031/droonga.000" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.52:10031/droonga.000" } } + ] + } + ] + }, + "Testing": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.60:20031/droonga.000" } } + ] + } + ] + } + } +} +~~~ + +### 既存のreplicaの削除 + +クラスタ内のデータセット`Default`から既存のreplicaノード`192.168.100.51`を取り除くコマンド列は以下の通りです: + +~~~ +$ droonga-engine-catalog-modify \ + --source /tmp/catalog.json \ + --no-update \ + --remove-replica-hosts 192.168.100.51 +~~~ + +省略されたオプションを含めた完全な指定はこのようになります: + +~~~ +$ droonga-engine-catalog-modify \ + --source /tmp/catalog.json \ + --output - \ + --no-update \ + --dataset Default \ + --remove-replica-hosts 192.168.100.51 +~~~ + +変更された`catalog.json`は以下の通りです: + +~~~ +{ + "version": 2, + "effectiveDate": "2015-05-08T09:02:12+00:00", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.50:10031/droonga.000" } } + ] + } + ] + }, + "Testing": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.60:20031/droonga.000" } } + ] + } + ] + } + } +} +~~~ + +データセットから全てのreplicaノードを取り除くこともできます: + +~~~ +$ droonga-engine-catalog-modify \ + --source /tmp/catalog.json \ + --no-update \ + --remove-replica-hosts 192.168.100.52,192.168.100.51 +{ + "version": 2, + "effectiveDate": "2015-05-08T09:02:12+00:00", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [] + }, + "Testing": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.60:20031/droonga.000" } } + ] + } + ] + } + } +} +~~~ + +しかし、これは`catalog.json`としては不正な内容です。 +このコマンドを使って空のデータセットに対し再びreplicaノードを追加することはできません。 +このような壊れた`catalog.json`を修復するには、[`droonga-engine-catalog-generate`コマンド](../droonga-engine-catalog-generate/)を使って再生成する必要があります。 + + +### 複数のデータセットのreplicaノードのリストを一度に更新する + +新しいreplicaノード`192.168.100.52`をデータセット`Default`へ、もう1つの新しいreplicaノード`192.168.100.61`をデータセット`Testing`へ追加するコマンド列は以下の通りです: + +~~~ +$ droonga-engine-catalog-modify \ + --source /tmp/catalog.json \ + --no-update \ + --add-replica-hosts 192.168.100.52 \ + --dataset Testing \ + --add-replica-hosts 192.168.100.61 +~~~ + +省略されたオプションを含めた完全な指定はこのようになります: + +~~~ +$ droonga-engine-catalog-modify \ + --source /tmp/catalog.json \ + --output - \ + --no-update \ + --dataset Default \ + --add-replica-hosts 192.168.100.52 \ + --dataset Testing \ + --add-replica-hosts 192.168.100.61 +~~~ + +変更された`catalog.json`は以下の通りです: + +~~~ +{ + "version": 2, + "effectiveDate": "2015-05-08T09:02:12+00:00", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.50:10031/droonga.000" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.51:10031/droonga.000" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.52:10031/droonga.000" } } + ] + } + ] + }, + "Testing": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.60:20031/droonga.000" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.61:20031/droonga.000" } } + ] + } + ] + } + } +} +~~~ + +このコマンドはポート番号とタグ名をデータセット固有の設定として認識するため、`Default`配下の新しいreplicaにはポート番号として`10031`が、`Testing`配下の新しいreplicaにはポート番号として`20031`が使われています。 + +別の場合として、2つのデータセット`Default`と`Testing`の間でreplicaノードを交換するコマンド列も示します: + +~~~ +$ droonga-engine-catalog-modify \ + --source /tmp/catalog.json \ + --no-update \ + --replica-hosts 192.168.100.60 \ + --dataset Testing \ + --replica-hosts 192.168.100.50,192.168.100.51 +~~~ + +省略されたオプションを含めた完全な指定はこのようになります: + +~~~ +$ droonga-engine-catalog-modify \ + --source /tmp/catalog.json \ + --output - \ + --no-update \ + --dataset Default \ + --replica-hosts 192.168.100.60 \ + --dataset Testing \ + --replica-hosts 192.168.100.50,192.168.100.51 +~~~ + +変更された`catalog.json`は以下の通りです: + +~~~ +{ + "version": 2, + "effectiveDate": "2015-05-08T09:02:12+00:00", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.60:10031/droonga.000" } } + ] + } + ] + }, + "Testing": { + "nWorkers": 4, + "plugins": ["groonga", "search", "crud", "dump", "system", "catalog"], + "schema": {}, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.50:20031/droonga.000" } } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { "weight": 100, + "volume": { "address": "192.168.100.51:20031/droonga.000" } } + ] + } + ] + } + } +} +~~~ + +個々のvolumeのポート番号が変化したことに注意して下さい。 +ポート番号はデータセットの方に紐付けられているため、ポート番号が入れ替わっています。 + +## パラメータ {#parameters} + +`--source=PATH` +: 変更される対象の`catalog.json`の読み込み元パス。 + `-`を指定した場合は標準入力から`catalog.json`を受け取ります。 + 指定されたパスの位置にある既存のファイルは、確認無しに上書きされます。 + 既定値は、そのコンピュータ上に設定される`droonga-engine`サービスの`catalog.json`の位置(`/home/droonga-engine/droonga/catalog.json`)です。 + +`--output=PATH` +: 変更された`catalog.json`の保存先パス。 + `-`を指定した場合は標準出力に対して出力します。 + 指定されたパスの位置にある既存のファイルは、確認無しに上書きされます。 + 既定値は`-`です。 + +`--[no-]update` +: 読み込んだファイル自体を更新するかどうか。 + + * `--update`は、`--source`オプションで指定された入力ファイル自体を上書きします。 + * `--no-update`は、変更後の`catalog.json`を`--output`で指定された出力先に出力します。 + + 既定値は`--update`です。 + +`--dataset=NAME` +: 変更する対象の既存データセットの名前。 + 複数のデータセットを変更できるように、このオプションは複数回指定できます。 + 既定値は`Default`です。 + +`--replica-hosts=NAME1,NAME2,...` +: 先行する`--dataset`オプションで定義されたデータセットにおいて、replicaとして使う1つ以上のEngineノードのホスト名。 + このオプションを指定した場合、データセット内の既存のreplicaノードは全て置き換えられます。 + +`--add-replica-hosts=NAME1,NAME2,...` +: 先行する`--dataset`オプションで定義されたデータセットに対して追加する、1つ以上のEngineノードのホスト名。 + +`--remove-replica-hosts=NAME1,NAME2,...` +: 先行する`--dataset`オプションで定義されたデータセットから取り除く、1つ以上のEngineノードのホスト名。 + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-engine`の一部としてインストールされます。 + +~~~ +# gem install droonga-engine +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-engine-configure/index.md (+121 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-engine-configure/index.md 2015-11-15 23:29:56 +0900 (43c0e3d) @@ -0,0 +1,121 @@ +--- +title: droonga-engine-configure +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-engine-configure/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-engine-configure`は、そのコンピュータ自身を`droonga-engine`のノードとして設定します。 + +このコマンドの最も代表的な用途は、[`droonga-engine-join`コマンド](../droonga-engine-join/)で管理しやすいように、コンピュータをクリーンで空の状態のDroonga Engineノードとしてリセットする事です。 + +このコマンドはコンピュータをどのように設定するかを対話的に尋ねてきます: + +~~~ +# droonga-engine-configure +The droonga-engine service is now running. +Before reconfiguration, the service is going to be stopped and this node will be unjoined from the cluster. +Are you sure you want to continue reconfiguration? (y/N): y +Do you want all data to be cleared? (y/N): y +Do you want the configuration file "droonga-engine.yaml" to be regenerated? (y/N): y +Do you want the file "catalog.json" to be regenerated? (y/N): y +host [192.168.100.50]: +port [10031]: +tag [droonga]: +log level (trace,debug,info,warn,error,fatal) [warn]: +~~~ + +プランが既に固まっているのであれば、コマンドラインオプションを使ってサイレントに実行する事もできます: + +~~~ +# droonga-engine-configure \ + --no-prompt \ + --clear \ + --reset-config \ + --reset-catalog \ + --host nodeX \ + --port 20032 \ + --tag droonga \ + --log-level info +~~~ + +`droonga-engine`サービスがサービスとして正しく設定されている場合、このコマンドはインストール済みのサービスを設定するためだけに動作し、(サービスの利用においては使われない)いくつかのオプションは無視されます。 + + +## パラメータ {#parameters} + +`--no-prompt` +: 対話的な入力プロンプトを表示しない。 + このオプションが指定された場合、以下のオプションで指定されなかった設定項目は全て既定の値で埋められます。 + オプションが指定されない場合、以下の各項目に対応する設問が表示されます。 + +`--clear` +: `droonga-engine`サービスのデータディレクトリにある全てのデータを消去します。 + +`--reset-config` +: 既存の`droonga-engine.yaml`を新しい物に置き換えます。 + このオプションが指定された場合、`droonga-engine.yaml`は確認無しに上書きされます。 + オプションが指定されず、既存の`droonga-engine.yaml`が存在する場合、上書きして良いかどうかが尋ねられます。 + +`--reset-catalog` +: 既存の`catalog.json`を、孤立した単一のEngineノードのみを含む内容の新しい物に置き換えます。 + このオプションが指定された場合、`catalog.json`は確認無しに上書きされます。 + オプションが指定されず、既存の`catalog.json`が存在する場合、上書きして良いかどうかが尋ねられます。 + +`--host=NAME` +: Engineノード自身のホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--port=PORT` +: クライアントや他のノードからの接続を待ち受けるポートの番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: 入力メッセージとして受け付けるタグ名。 + 既定値は`droonga`です。 + +`--internal-connection-lifetime=SECONDS` +: 内部的な接続において、応答のないメッセージの処理を打ち切るまでの待ち時間(単位:秒)。 + 既定値は`60`です。 + +`--log-level=LEVEL` +: ロガー用のログレベル。 + 取り得る値は`trace`、`debug`、`info`、`warn`、`error`、`fatal`のうちのいずれかです。 + 既定値は`warn`です。 + +`--log-file=PATH` +: ログメッセージの出力先ファイルのパス。 + このオプションが指定されなかった場合、ログは標準出力に出力されます。 + +`--daemon`, `--no-daemon` +: デーモンとして実行するか、通常のプロセスとして実行するか。 + ただし、`service droonga-engine start`コマンドで開始されるサービスについては常にデーモンとして実行されます。 + +`--pid-file=PATH` +: デーモンとして実行されたプロセスのプロセスIDの出力先ファイルのパス。 + ただし、`service droonga-engine start`コマンドで開始されるサービスについては、プロセスIDは常にプラットフォームごとの適切な位置に出力されます。 + +`--base-dir=PATH` +: すべての`droonga-engine`関係のファイルが格納されるデータディレクトリのパス。 + ただし、`service droonga-engine start`コマンドで開始されるサービスについては、必ず`/home/droonga-engine/droonga/`が使われます。 + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-engine`の一部としてインストールされます。 + +~~~ +# gem install droonga-engine +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-engine-join/index.md (+109 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-engine-join/index.md 2015-11-15 23:29:56 +0900 (085bb8d) @@ -0,0 +1,109 @@ +--- +title: droonga-engine-join +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-engine-join/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-engine-join`は、孤立したDroonga Engineノードを既存のDroongaクラスタに新たなreplicaノードとして参加させます。 + +例えば、既存クラスタのreplicaノードとなっている`192.168.100.50`というDroonga Engineノードがあり、同一ネットワークセグメント内の事前設定済みの孤立したDroonga Engineノード`192.168.100.10`にログインしている場合、`192.168.100.10`をクラスタに新たなreplicaノードとして参加させるコマンド列は以下のようになります: + +~~~ +(on 192.168.100.10) +$ droonga-engine-join --host 192.168.100.10 \ + --receiver-host 192.168.100.10 \ + --replica-source-host 192.168.100.50 +Start to join a new node 192.168.100.10 + to the cluster of 192.168.100.50 + via 192.168.100.10 (this host) + port = 10031 + tag = droonga + dataset = Default + +Source Cluster ID: 8951f1b01583c1ffeb12ed5f4093210d28955988 + +Changing role of the joining node... +Configuring the joining node as a new replica for the cluster... +Registering new node to existing nodes... +Changing role of the source node... +Getting the timestamp of the last processed message in the source node... +The timestamp of the last processed message at the source node: 2015-05-07T02:39:50.334377Z +Setting new node to ignore messages older than the timestamp... +Copying data from the source node... +100% done (maybe 00:00:00 remaining) +Restoring role of the source node... +Restoring role of the joining node... +Done. +~~~ + +[Droongaクラスタに新しいreplicaノードを追加する操作についてのチュートリアル](/ja/tutorial/add-replica/)も併せて参照して下さい。 + + +## パラメータ {#parameters} + +`--no-copy` +: コピー元ノードからデータをコピーしない。 + このオプションを指定した場合、ノードはデータを同期されずにそのままreplicaノードとしてクラスタに追加されます。 + +`--host=NAME` +: クラスタに参加する新しいEngineノードのホスト名。 + このパラメータは必須です。 + +`--replica-source-host=NAME` +: 新たにノードを参加させるクラスタ内でデータのコピー元にするノードのホスト名。 + このパラメータは必須です。 + +`--port=PORT` +: 各Engineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: 各Engineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + +`--dataset=NAME` +: 新たなノードをreplicaとして参加させる対象のデータセットの名前。 + 既定値は`Default`です。 + +`--receiver-host=NAME` +: このコマンドを実行しているコンピュータのホスト名。 + 既定値は、そのコンピュータのホスト名として推測される名前です。 + +`--records-per-second=N` +: 1秒間にコピーするレコードの最大数。 + `-1`を指定した場合、"無制限"を意味します。 + 既定値は`100`です。 + +`--progress-interval-seconds=SECONDS` +: データコピーの進捗を報告する間隔の秒数。 + 既定値は`3`です。 + +`--verbose` +: 内部的な操作の詳細を出力します。 + 主にデバッグ用のオプションです。 + +`-h`, `--help` +: コマンドの使い方の説明を表示します。 + + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-engine`の一部としてインストールされます。 + +~~~ +# gem install droonga-engine +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-engine-set-role/index.md (+84 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-engine-set-role/index.md 2015-11-15 23:29:56 +0900 (8a3794e) @@ -0,0 +1,84 @@ +--- +title: droonga-engine-set-role +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-engine-set-role/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-engine-set-role`は、あるDroonga Engineノードのロールを任意のロールに変更します。 + +Droonga Engineノードは、流入してきたメッセージを自分で処理するかどうかを、[メッセージの`targetRole`フィールド](../../message/#request-targetRole)の値に基づいて決定します。 +[`droonga-engine-join`コマンド](../droonga-engine-join/)は操作対象のノードのロールを変更しますが、もし操作が意図せず中断されてしまった場合、それらのノードはサービス提供用としては無効化されたままになってしまうことがあります。 +そのような場合には、このコマンドを使ってそれらのノードのロールを適切に変更することで、ノードを再度有効化できます。 + +例えば、新たに追加されるreplicaノードのためのデータコピー元として使われた`192.168.100.50`というDroonga Engineノードがあり、同一ネットワークセグメント内のコンピュータ`192.168.100.10`にログインしている場合、`192.168.100.50`を再度有効化するコマンド列は以下のようになります: + +~~~ +(on 192.168.100.10) +$ droonga-engine-set-role --host 192.168.100.50 \ + --role service-provider +Setting role of 192.168.100.50:10031/droonga to service-provider... +Done. +~~~ + +[Droongaクラスタに新しいreplicaノードを追加する操作についてのチュートリアル](/ja/tutorial/add-replica/)も併せて参照して下さい。 + + +## パラメータ {#parameters} + +`--role=ROLE` +: 対象Engineノードのための新しいロール。 + このパラメータは必須です。 + 取り得る値: + + * `service-provider`: + ノードはサービス提供用として有効化されます。 + * `absorb-source`: + ノードはサービス提供用として無効化され、データのコピー元に設定されます。 + * `absorb-destination`: + ノードはサービス提供用として無効化され、データのコピー先に設定されます。 + +`--host=NAME` +: ロールを変更するEngineノードのホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--port=PORT` +: Engineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + + この値は、実際にはこの操作の処理のためには使われませんが、ノード自体を識別するために使われます。 + +`--tag=TAG` +: Engineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + + この値は、実際にはこの操作の処理のためには使われませんが、ノード自体を識別するために使われます。 + +`--verbose` +: 内部的な操作の詳細を出力します。 + 主にデバッグ用のオプションです。 + +`-h`, `--help` +: コマンドの使い方の説明を表示します。 + + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-engine`の一部としてインストールされます。 + +~~~ +# gem install droonga-engine +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-engine-unjoin/index.md (+74 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-engine-unjoin/index.md 2015-11-15 23:29:56 +0900 (520c6f1) @@ -0,0 +1,74 @@ +--- +title: droonga-engine-unjoin +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-engine-unjoin/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-engine-unjoin`は、既存のDroongaクラスタからDroonga Engineノードを取り除きます。 + +例えば、既存クラスタのreplicaノードとなっている`192.168.100.50`というDroonga Engineノードがあり、同一ネットワークセグメント内のコンピュータ`192.168.100.10`にログインしている場合、`192.168.100.50`をクラスタから取り除くコマンド列は以下のようになります: + +~~~ +(on 192.168.100.10) +$ droonga-engine-unjoin --host 192.168.100.50 \ + --receiver-host 192.168.100.10 +Start to unjoin a node 192.168.100.50:10031/droonga + by 192.168.100.10 (this host) + +Unjoining replica from the cluster... +Done. +~~~ + +[Droongaクラスタに新しいreplicaノードを追加する操作についてのチュートリアル](/ja/tutorial/add-replica/)も併せて参照して下さい。 + + +## パラメータ {#parameters} + +`--host=NAME` +: クラスタから取り除かれるEngineノードのホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--port=PORT` +: Engineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: Engineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + +`--dataset=NAME` +: ノードを取り除く対象のデータセットの名前。 + 既定値は`Default`です。 + +`--receiver-host=NAME` +: このコマンドを実行しているコンピュータのホスト名。 + 既定値は、そのコンピュータのホスト名として推測される名前です。 + +`--verbose` +: 内部的な操作の詳細を出力します。 + 主にデバッグ用のオプションです。 + +`-h`, `--help` +: コマンドの使い方の説明を表示します。 + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-engine`の一部としてインストールされます。 + +~~~ +# gem install droonga-engine +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-groonga/index.md (+170 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-groonga/index.md 2015-11-15 23:29:56 +0900 (5cca3f3) @@ -0,0 +1,170 @@ +--- +title: droonga-groonga +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-groonga/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-groonga`は、Droongaクラスタに対してコマンドラインインターフェース経由でGroongaサーバのように通信する機能を提供します。 + +例えば、`192.168.100.50`というDroonga Engineノードがあり、同一ネットワークセグメント内のコンピュータ`192.168.100.10`にログインしている場合、全てのテーブルの一覧を出力するコマンド列は以下のようになります: + +~~~ +(on 192.168.100.10) +$ droonga-groonga --host 192.168.100.50 --receiver-host 192.168.100.10 --pretty \ + table_list +[ + [ + 0, + 1431000097.1314175, + 0.00024175643920898438 + ], + [ + [ + [ + "id", + "UInt32" + ], + [ + "name", + "ShortText" + ... + ] +] +~~~ + +このコマンドは、Groonga互換コマンドのメッセージを[`droonga-request`](../droonga-request/)を用いて送信する操作を簡単に行う物です。 +上記コマンド列によってもたらされる結果は、以下のコマンド列の結果と実質的に同一です: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"table_list"}' | + droonga-request --report-request --host 192.168.100.50 --receiver-host 192.168.100.10 +Request: { + "type": "table_list", + "id": "1431000097.1242323", + "date": "2015-05-07T12:01:37.124254Z", + "dataset": "Default" +} +Elapsed time: 0.011710191 +{ + "inReplyTo": "1431000097.1242323", + "statusCode": 200, + "type": "table_list.result", + "body": [ + [ + 0, + 1431000097.1314175, + 0.00024175643920898438 + ], + [ + [ + [ + "id", + "UInt32" + ], + [ + "name", + "ShortText" + ... + ] + ] +} +~~~ + +[Groonga互換コマンドのリファレンス](../../commands/)、および[Groongaのリファレンスマニュアル](http://groonga.org/ja/docs/reference/command.html)も併せて参照して下さい。 + +## `groonga`コマンドとの互換性 {#compatibility} + +このコマンドは[`groonga`コマンドのクライアントモードおよびスタンドアロンモード](http://groonga.org/ja/docs/reference/executables/groonga.html)のように動作するよう設計されています。 +このコマンドに与えられた、Droonga固有のオプションを除いた残りの全てのコマンドライン引数は、`groonga`コマンドのコマンドライン引数と同様に動作します。 +例: + +~~~ +(on 192.168.100.10) +$ GROONGA="droonga-groonga --host 192.168.100.50 --receiver-host 192.168.100.10 --pretty " +$ $GROONGA table_list +$ $GROONGA column_list --table Store +$ $GROONGA select --table Store --match_columns name --query ave --limit 5 --output_columns _key,name +~~~ + +ただし、現在の所`groonga`コマンドの以下の機能にはまだ対応していません: + + * 標準入力経由での複数コマンドの実行 + * コマンドライン引数の後続行によって与えられる`load`コマンドのための値 + * Droongaが対応していないGroongaの機能 + + +## パラメータ {#parameters} + +Groonga風のコマンドライン引数と以下のDroonga固有のオプションが利用できます。 + +`--pretty` +: 結果をpretty print形式のJSONで出力します。 + +`--host=NAME` +: メッセージの送信先となるEngineノードのホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--port=PORT` +: Engineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: Engineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + +`--dataset=NAME` +: メッセージの送信先データセット名。 + 既定値は`Default`です。 + +`--receiver-host=NAME` +: このコマンドを実行しているコンピュータのホスト名。 + 既定値は、そのコンピュータのホスト名として推測される名前です。 + +`--target-role=ROLE` +: メッセージを処理できるEngineノードのロール。 + 以下のいずれかを指定します: + + * `service-provider`: + メッセージは、クラスタ内でサービスを提供中のノードで処理されます。 + データ抽出操作に関わるノードには、後から遅れてメッセージが伝搬します。 + * `absorb-source`: + メッセージは、クラスタへのノード追加操作におけるデータコピー元となっているノードで処理されます。 + サービスを提供中のノード、並びにデータコピー先となっているノードへは、メッセージは伝搬しません。 + * `absorb-destination`: + メッセージは、クラスタへのノード追加操作におけるデータコピー先となっているノードで処理されます。 + サービスを提供中のノード、並びにデータコピー元となっているノードへは、メッセージは伝搬しません。 + * `any`: + メッセージは、`--host`で指定されたノードで処理されます。 + + 既定値は`any`です。 + +`--timeout=SECONDS` +: 応答がない接続を打ち切るまでの待ち時間(単位:秒)です。 + 既定値は`3`です。 + +`-h`, `--help` +: コマンドの使い方の説明を表示します。 + + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-client`の一部としてインストールされます。 + +~~~ +# gem install droonga-client +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-http-server-configure/index.md (+180 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-http-server-configure/index.md 2015-11-15 23:29:56 +0900 (69b3d0d) @@ -0,0 +1,180 @@ +--- +title: droonga-http-server-configure +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-http-server-configure/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-http-server-configure`は、そのコンピュータ自身を`droonga-http-server`のノードとして設定します。 + +このコマンドの最も代表的な用途は、コンピュータをクリーンな状態のHTTPサーバー用ノードとしてリセットする事です。 +このコマンドはコンピュータをどのように設定するかを対話的に尋ねてきます: + +~~~ +# droonga-http-server-configure +Do you want the configuration file "droonga-http-server.yaml" to be regenerated? (y/N): y +IP address to accept requests from clients (0.0.0.0 means "any IP address") [0.0.0.0]: +port [10041]: +hostname of this node [nodeX]: +hostnames of droonga-engine nodes (comma, vertical bar, or white-space separated) [nodeX]: +port number of the droonga-engine node [10031]: +tag of the droonga-engine node [droonga]: +default dataset [Default]: +timeout for unresponsive connections (in seconds) [3]: +path to the access log file [droonga-http-server.access.log]: +path to the system log file [droonga-http-server.system.log]: +log level for the system log (silly,debug,verbose,info,warn,error) [warn]: +maximum size of the response cache [100]: +time to live of cached responses, in seconds [60]: +enable "trust proxy" configuration (y/N): +path to the document root [/usr/local/lib/node_modules/droonga-http-server/public/groonga-admin]: +environment [production]: +~~~ + +プランが既に固まっているのであれば、コマンドラインオプションを使ってサイレントに実行する事もできます: + +~~~ +# droonga-http-server-configure \ + --no-prompt \ + --reset-config \ + --host 0.0.0.0 \ + --port 10041 \ + --droonga-engine-host-names node0,node1,node2 \ + --droonga-engine-port 10031 \ + --tag droonga \ + --system-log-level info +~~~ + +`droonga-http-server`サービスがサービスとして正しく設定されている場合、このコマンドはインストール済みのサービスを設定するためだけに動作し、(サービスの利用においては使われない)いくつかのオプションは無視されます。 + + +## パラメータ {#parameters} + +`--no-prompt` +: 対話的な入力プロンプトを表示しない。 + このオプションが指定された場合、以下のオプションで指定されなかった設定項目は全て既定の値で埋められます。 + オプションが指定されない場合、以下の各項目に対応する設問が表示されます。 + +`--reset-config` +: 既存の`droonga-http-server.yaml`を新しい物に置き換えます。 + このオプションが指定された場合、`droonga-http-server.yaml`は確認無しに上書きされます。 + オプションが指定されず、既存の`droonga-http-server.yaml`が存在する場合、上書きして良いかどうかが尋ねられます。 + +`--host=HOST` +: リッスンするホスト名。 + 言い換えると、これはバインドアドレスを示します。 + 既定値は`0.0.0.0`(そのコンピュータに割り当てられた全てのIPアドレスとホスト名で接続を受け付ける)です。 + +`--port=PORT` +: クライアントからの接続を待ち受けるポートの番号。 + 既定値は`10041`です。 + +`--receiver-host-name=NAME` +: HTTPサーバ用ノード自身のホスト名。 + ここで指定する名前は、全てのDroonga Engineノードから名前解決できる物でなくてはなりません。 + EngineノードはHTTPサーバによって仲介されたリクエストに対するレスポンスを含むすべてのメッセージを、ここで指定されたホスト名宛に送信します。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--droonga-engine-host-names=NAME1,NAME2,...` +: 起動時に接続を試みるDroonga Engineノードのホスト名のリスト。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--droonga-engine-port=PORT` +: Droonga Engineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: Droonga Engineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + +`--default-dataset=NAME` +: メッセージの既定の送信先データセット名。 + 既定値は`Default`です。 + +`--default-timeout=SECONDS` +: 応答がない接続を打ち切るまでの待ち時間(単位:秒)。 + 既定値は`3`です。 + +`--access-log-file=PATH` +: アクセスログの出力先ファイルのパス。 + `-`を指定した場合、ログは標準出力に出力されます。 + 既定値は`-`です。 + +`--system-log-file=PATH` +: システムログの出力先ファイルのパス。 + `-`を指定した場合、ログは標準出力に出力されます。 + 既定値は`-`です。 + +`--system-log-level=LEVEL` +: システムログ用ロガーのログレベル。 + 取り得る値は`silly`/`trace`、`debug`、`verbose`、`info`、`warn`、`error`のうちのいずれかです。 + 既定値は`warn`です。 + +`--cache-size=N` +: レスポンスキャッシュの最大件数。 + この設定は、`/d/select`などのいくつかのエンドポイントについてのみ反映されます。 + 既定値は`100`です。 + +`--cache-ttl-in-seconds=SECONDS` +: レスポンスキャッシュの寿命(単位:秒)。 + この設定は、`/d/select`などのいくつかのエンドポイントについてのみ反映されます。 + 既定値は`60`です。 + +`--enable-trust-proxy`, `--disable-trust-proxy` +: 「プロキシを信用する」設定を有効化するかどうか。 + `droonga-http-server`のサービスをリバースプロキシの背後で動作させる場合、この設定を有効化する必要があります。 + 既定値は`--disable-trust-proxy`です。 + +`--document-root=PATH` +: ドキュメントルートへのパス。 + 既定値は`(droonga-http-serverのインストール先ディレクトリ)/public/groonga-admin`です。 + +`--plugins=PLUGIN1,PLUGIN2,...` +: 有効化するプラグインのリスト。 + 取り得る値; + + * `./api/rest`: `search`コマンドのためのREST形式のエンドポイントを提供します。 + * `./api/groonga`: Groonga互換のエンドポイントを提供します。 + * `./api/droonga`: Droongaネイティブコマンド用の一般的なエンドポイントを提供します。 + + 既定の状態では、全てのプラグインが有効化されます。 + +`--daemon` +: デーモンとして実行する + ただし、`service droonga-http-server start`コマンドで開始されるサービスについては常にデーモンとして実行されます。 + +`--pid-file=PATH` +: デーモンとして実行されたプロセスのプロセスIDの出力先ファイルのパス。 + ただし、`service droonga-http-server start`コマンドで開始されるサービスについては、プロセスIDは常にプラットフォームごとの適切な位置に出力されます。 + +`--environment=ENVIRONMENT` +: サーバの実行時の環境。 + 取り得る値: + + * `development` + * `production` (既定値) + * `testing` + +`-h`, `--help` +: コマンドの使い方の説明を表示します。 + +## インストール方法 {#install} + +このコマンドは、npmのパッケージ`droonga-http-server`の一部としてインストールされます。 + +~~~ +# npm install -g droonga-http-server +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-request/index.md (+342 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-request/index.md 2015-11-15 23:29:56 +0900 (7944df4) @@ -0,0 +1,342 @@ +--- +title: droonga-request +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-request/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-request`は、任意のメッセージをDroongaクラスタに送り、レスポンスとして得られた結果を出力します。 + +このコマンドはDroongaネイティブプロトコルとHTTPの両方に対応しています。 +Droonga Engineノードに対しては、Droongaネイティブのメッセージを直接送れます。 + + +大量のメッセージを一気に送信したい場合は、[`droonga-send`コマンドの説明](../droonga-send/)も併せて参照して下さい。 + +## 使い方 {#usage} + +### 基本的な使い方 + +例えば、`192.168.100.50`というDroonga Engineノードがあり、同一ネットワークセグメント内のコンピュータ`192.168.100.10`にログインしている場合、[`system.status`](../../commands/system/status/)コマンドのメッセージを送信するコマンド列は以下のようになります: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"system.status"}' | + droonga-request --host 192.168.100.50 --receiver-host 192.168.100.10 +Elapsed time: 0.00900742 +{ + "inReplyTo": "1430963525.9829412", + "statusCode": 200, + "type": "system.status.result", + "body": { + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "node0:55329/droonga @ node0:10031/droonga" + } +} +~~~ + +1行目はレスポンスを得るまでにかかった時間です。 +後の行はレスポンスメッセージとして得られた内容です。 + +[メッセージの形式のリファレンス](../../message/)の説明にある通り、`id`、`date`、`dataset`の各フィールドはリクエストメッセージの必須フィールドです。 +与えられたメッセージがそれらを持っていなかった場合、このコマンドは初期状態で、適切な値を推測または生成して補います。 +実際に送信された補完後のメッセージを見るには、`--report-request`オプションを指定して下さい: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"system.status"}' | + droonga-request --report-request --host 192.168.100.50 --receiver-host 192.168.100.10 +Request: { + "type": "system.status", + "id": "1430963525.9829412", + "date": "2015-05-07T02:39:50.334377Z", + "dataset": "Default" +} +Elapsed time: 0.00900742 +... +~~~ + +利用可能な全てのコマンドの一覧については、[コマンドリファレンス](../../commands/)を併せて参照して下さい。 + +### 他のコマンドとの連携 + +このメッセージは標準入力を通じて送信するメッセージを受け取れます。 +上記の例のように、`echo`、`cat`、およびその他のコマンドをこのコマンドのための入力ソースとして利用できます。 +例えば、[`drndump`](../drndump/)の出力もそのまま入力ソースとして利用できます: + +~~~ +(on 192.168.100.10) +$ drndump --host 192.168.100.50 --receiver-host 192.168.100.10 | \ + droonga-request --host 192.168.100.60 --receiver-host 192.168.100.10 \ + > /dev/null +~~~ + +### ファイルからの入力 + +テキストファイルを入力ソースとして使うこともできます。 +このコマンドは以下のように、コマンドライン引数として指定されたファイルの内容を読み込んで利用します: + +~~~ +(on 192.168.100.10) +$ cat /tmp/message.json +{"type":"system.status"} +$ droonga-request --host 192.168.100.60 --receiver-host 192.168.100.10 /tmp/message.json +Elapsed time: 0.00900742 +{ + "inReplyTo": "1430963525.9829412", + "statusCode": 200, + "type": "system.status.result", + "body": { + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "node0:55329/droonga @ node0:10031/droonga" + } +} +~~~ + +### 複数のメッセージを一度に送る + +このコマンドは複数のメッセージを順番に送る事もできます。 +複数メッセージの一括送信は、単に、複数のメッセージを入力として与えるだけで行えます: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"system.status"} {"type":"system.statistics.object.count","body":{"output":["total"]}}' | + droonga-request --host 192.168.100.50 --receiver-host 192.168.100.10 +Elapsed time: 0.007365724 +{ + "inReplyTo": "1430964599.844579", + "statusCode": 200, + "type": "system.status.result", + "body": { + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "node0:55329/droonga @ node0:10031/droonga" + } +} +Elapsed time: 0.014172429 +{ + "inReplyTo": "1430964599.8521488", + "statusCode": 200, + "type": "system.statistics.object.count.result", + "body": { + "total": 549 + } +} +~~~ + +全てのレスポンスに伴う処理結果は、順番に標準出力に出力されます。 + +もちろん、以下のようにしてソースファイル内に複数のメッセージを含めることもできます: + +~~~ +(on 192.168.100.10) +$ cat /tmp/messages.jsons +{"type":"system.status"} +{"type":"system.statistics.object.count", + "body":{"output":["total"]}} +$ droonga-request --host 192.168.100.60 --receiver-host 192.168.100.10 /tmp/messages.jsons +Elapsed time: 0.007365724 +{ + "inReplyTo": "1430964599.844579", + "statusCode": 200, + "type": "system.status.result", + "body": { + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "node0:55329/droonga @ node0:10031/droonga" + } +} +Elapsed time: 0.014172429 +{ + "inReplyTo": "1430964599.8521488", + "statusCode": 200, + "type": "system.statistics.object.count.result", + "body": { + "total": 549 + } +} +~~~ + +個々のリクエストは1つ前のリクエストに対するレスポンスが得られてから送られるため、大量のメッセージがある場合には非常に時間がかかります。 +そのような場合のための代わりの選択肢としては[`droonga-send`コマンド](../droonga-send/)があります。 + + +### DroongaクラスタとHTTPで通信する + +このコマンドはDroonga Engineとの接続だけでなく、以下のようにしてHTTPプロトコルアダプターとも通信できます: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"system.statistics.object.count","body":{"output":["total"]}}' | + droonga-request --report-request --protocol http --host 192.168.100.50 --port 10041 +Request: { + "method": "GET", + "path": "/droonga/system/statistics/object/count?output[]=total", + "headers": { + "Accept": "*/*", + "User-Agent": "Ruby" + }, + "body": null +} +Elapsed time: 0.026170325 +{ + "total": 549 +} +~~~ + +HTTPプロトコルアダプタに接続する場合は、使い方が若干変わります: + + * `--protocol http` (`--protocol=http`)オプションを指定する必要があります。 + * `--port`オプションを使って、HTTPプロトコルアダプター用に正しいポート番号を指定する必要があります。 + (このオプションの値は既定の状態ではDroonga Engineノード用に`10031`になっていますが、通常、HTTPプロトコルアダプターは`10041`番ポートを使います。) + * `--receiver-host`オプションは使用しません。 + +この利用形態においては、HTTP用のリクエストメッセージを入力として与えることができます。 +通常のDroongaネイティブプロトコルのメッセージは、上記の例のように自動的にHTTP用のリクエストメッセージに変換されます。 + +同様の体裁で、独自のHTTPリクエストメッセージを入力として与えることもできます。 +以下は、POSTメソッドで、独自のユーザーエージェント文字列を伴ったPOSTメソッドのHTTPリクエストを送信する例です: + +~~~ +(on 192.168.100.10) +$ echo '{"method":"POST","path": "/droonga/system/statistics/object/count","headers":{"User-Agent":"Droonga Client"},"body":{"output":["total"]}}' | + droonga-request --report-request --protocol http --host 192.168.100.50 --port 10041 +Request: { + "method": "POST", + "path": "/droonga/system/statistics/object/count", + "headers": { + "User-Agent": "Droonga Client", + "Accept": "*/*" + }, + "body": "{\"output\":[\"total\"]}" +} +Elapsed time: 0.026170325 +{ + "total": 549 +} +~~~ + + +## パラメータ {#parameters} + + +`--host=NAME` +: メッセージの送信先となるDroongaクラスタの接続先ホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--port=PORT` +: Droongaクラスタの接続先との通信に使うポート番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: Droongaクラスタの接続先との通信に使うタグ名。 + 既定値は`droonga`です。 + +`--protocol=PROTOCOL` +: Droongaクラスタの接続先との通信に使うプロトコル。 + 取り得る値は以下の通りです: + + * `droonga` (既定値): Droonga Engineノードのネイティブプロトコル。 + * `http`: HTTP。 + +`--timeout=SECONDS` +: 応答がない接続を打ち切るまでの待ち時間(単位:秒)です。 + 既定値は`1`です。 + +`--receiver-host=NAME` +: このコマンドを実行しているコンピュータのホスト名。 + 既定値は、そのコンピュータのホスト名として推測される名前です。 + +`--[no-]report-request` +: 実際に送信されたリクエストのメッセージを報告するかどうか。 + 既定の状態は、`--no-report-request`が指定されている場合に等しいです。 + 実際に送られたメッセージを見るためには、`--report-request`オプションを手動で指定する必要があります。 + +`--[no-]report-elapsed-time` +: リクエストに対してレスポンスが得られるまでにかかった時間を報告するかどうか。 + 既定の状態は、`--report-elapsed-time`が指定されている場合に等しいです。 + 出力から`Elapsed time:`の行を消したい場合は、`--no-report-elapsed-time`オプションを手動で指定する必要があります。 + +`--default-dataset=NAME` +: メッセージの既定の送信先データセット名。 + 既定値は`Default`です。 + +`--default-target-role=ROLE` +: メッセージを処理できるEngineノードの既定のロール。 + 以下のいずれかを指定します: + + * `service-provider`: + メッセージは、クラスタ内でサービスを提供中のノードで処理されます。 + データ抽出操作に関わるノードには、後から遅れてメッセージが伝搬します。 + * `absorb-source`: + メッセージは、クラスタへのノード追加操作におけるデータコピー元となっているノードで処理されます。 + サービスを提供中のノード、並びにデータコピー先となっているノードへは、メッセージは伝搬しません。 + * `absorb-destination`: + メッセージは、クラスタへのノード追加操作におけるデータコピー先となっているノードで処理されます。 + サービスを提供中のノード、並びにデータコピー元となっているノードへは、メッセージは伝搬しません。 + * `any`: + メッセージは、`--host`で指定されたノードで処理されます。 + + 既定値は`any`です。 + +`--[no-]completion` +: 入力メッセージの必須フィールドを補完するかどうか。 + 既定の状態は、`--completion`が指定されている場合に等しいです。 + (既定のフィールドが欠落した)壊れたメッセージを意図的に送りたい場合は、`--no-completion`オプションを手動で指定する必要があります。 + +`--[no-]validation` +: 入力メッセージの妥当性を検証するかどうか。 + 既定の状態は、`--validation`が指定されている場合に等しいです。 + 妥当でない内容のメッセージを意図的に送りたい場合は、`--no-validation`オプションを手動で指定する必要があります。 + +`--help` +: コマンドの使い方の説明を表示します。 + + + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-client`の一部としてインストールされます。 + +~~~ +# gem install droonga-client +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-send/index.md (+268 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-send/index.md 2015-11-15 23:29:56 +0900 (2a3c7eb) @@ -0,0 +1,268 @@ +--- +title: droonga-send +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-send/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-request`は、レスポンスを待たずに任意のメッセージをDroongaクラスタに送ります。 + +このコマンドはDroongaネイティブプロトコルとHTTPの両方に対応しています。 +Droonga Engineノードに対しては、Droongaネイティブのメッセージを直接送れます。 + + +リクエストに対するレスポンスを見る必要がある場合は、[`droonga-request`コマンドの説明](../droonga-request/)も併せて参照して下さい。 + +## 使い方 {#usage} + +### 基本的な使い方 + +例えば、`192.168.100.50`というDroonga Engineノードがあり、同一ネットワークセグメント内のコンピュータ`192.168.100.10`にログインしている場合、[`add`](../../commands/add/)コマンドのメッセージを送信するコマンド列は以下のようになります: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"add","body":{"key":"id1","values":{"name":"Adam","age":20}}}' | + droonga-send --server droonga:192.168.100.50:10031/droonga +~~~ + +このコマンドは通常、何もメッセージを出力しません。 +リクエストが正常に処理されたかどうかを知る必要がある場合には、代わりに[`droonga-request`コマンド](../droonga-request/)を使って下さい。 + +[メッセージの形式のリファレンス](../../message/)の説明にある通り、`id`、`date`、`dataset`の各フィールドはリクエストメッセージの必須フィールドです。 +与えられたメッセージがそれらを持っていなかった場合、このコマンドは初期状態で、適切な値を推測または生成して補います。 +実際に送信された補完後のメッセージを見るには、`--report-request`オプションを指定して下さい: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"add","body":{"key":"id1","values":{"name":"Adam","age":20}}}' | + droonga-send --server droonga:192.168.100.50:10031/droonga --report-request +Request: { + "type": "add", + "body": { + "key": "id1", + "values": { + "name": "Adam", + "age": 20 + } + }, + "id": "1430990130.1114423", + "date": "2015-05-07T09:15:30.111467Z", + "dataset": "Default" +} +~~~ + +利用可能な全てのコマンドの一覧については、[コマンドリファレンス](../../commands/)を併せて参照して下さい。 + +### 他のコマンドとの連携 + +このメッセージは標準入力を通じて送信するメッセージを受け取れます。 +上記の例のように、`echo`、`cat`、およびその他のコマンドをこのコマンドのための入力ソースとして利用できます。 +例えば、[`drndump`](../drndump/)の出力もそのまま入力ソースとして利用できます: + +~~~ +(on 192.168.100.10) +$ drndump --host 192.168.100.50 --receiver-host 192.168.100.10 | \ + droonga-send --server droonga:192.168.100.50:10031/droonga +~~~ + +### ファイルからの入力 + +テキストファイルを入力ソースとして使うこともできます。 +このコマンドは以下のように、コマンドライン引数として指定されたファイルの内容を読み込んで利用します: + +~~~ +(on 192.168.100.10) +$ cat /tmp/message.json +{"type":"system.status"} +$ droonga-send --server droonga:192.168.100.50:10031/droonga /tmp/message.json +~~~ + +### 複数のメッセージを一度に送る + +このコマンドは複数のメッセージを一度に送る事もできます。 +複数メッセージの一括送信は、単に、複数のメッセージを入力として与えるだけで行えます: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"add","body":{"key":"id1","values":{"name":"Adam","age":20}}} {"type":"add","body":{"key":"id2","values":{"name":"Becky","age":30}}}' | + droonga-send --server droonga:192.168.100.50:10031/droonga +~~~ + +もちろん、以下のようにしてソースファイル内に複数のメッセージを含めることもできます: + +~~~ +(on 192.168.100.10) +$ cat /tmp/messages.jsons +{"type":"add","body":{"key":"id1","values":{"name":"Adam","age":20}}} +{"type":"add","body":{"key":"id2","values":{"name":"Becky","age":30}}} +$ droonga-send --server droonga:192.168.100.50:10031/droonga /tmp/messages.jsons +~~~ + +非常に多くのメッセージに対して、ラウンドロビン型のロードバランサーの挙動を再現するために、`--server`オプションを複数回使って複数のエンドポイントを指定することもできます: + +~~~ +(on 192.168.100.10) +$ droonga-send --server droonga:192.168.100.50:10031/droonga \ + --server droonga:192.168.100.51:10031/droonga \ + --server droonga:192.168.100.52:10031/droonga \ + /tmp/messages.jsons +~~~ + +この時、メッセージは各エンドポイントに並行してばらまかれます。 + +過負荷の状態を再現するには、以下のように`--messages-per-second`オプションを指定します: + +~~~ +(on 192.168.100.10) +$ droonga-send --server droonga:192.168.100.50:10031/droonga \ + --server droonga:192.168.100.51:10031/droonga \ + --server droonga:192.168.100.52:10031/droonga \ + --messages-per-second=1000 \ + /tmp/messages.jsons +~~~ + +このオプションの既定値は`100`ですが、コマンドを実行しているコンピュータの性能が十分に高ければ、制限を緩和することができます。 +このオプションによる制限値は各エンドポイントごとに適用されるため、この例の場合、クラスタは最大で毎秒3000件のメッセージを受け取ることになります。 + + +### DroongaクラスタとHTTPで通信する + +このコマンドはDroonga Engineとの接続だけでなく、以下のようにしてHTTPプロトコルアダプターとも通信できます: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"add","body":{"key":"id1","values":{"name":"Adam","age":20}}}' | + droonga-send --server http:192.168.100.50:10041 --report-request +Request: { + "method": "GET", + "path": "/droonga/add?key=id1&values[name]=Adam&values[age]=20", + "headers": { + "Accept": "*/*", + "User-Agent": "Ruby" + }, + "body": null +} +~~~ + +HTTPプロトコルアダプタに接続する場合は、使い方が若干変わります: + + * `--server`オプションにおいて、プロトコルとして`http:`を指定し、HTTPプロトコルアダプター用に正しいポート番号を指定する必要があります。 + ポート番号は既定の状態ではDroonga Engineノード用に`10031`になっていますが、通常、HTTPプロトコルアダプターは`10041`番ポートを使います。 + +この利用形態においては、HTTP用のリクエストメッセージを入力として与えることができます。 +通常のDroongaネイティブプロトコルのメッセージは、上記の例のように自動的にHTTP用のリクエストメッセージに変換されます。 + +同様の体裁で、独自のHTTPリクエストメッセージを入力として与えることもできます。 +以下は、POSTメソッドで、独自のユーザーエージェント文字列を伴ったPOSTメソッドのHTTPリクエストを送信する例です: + +~~~ +(on 192.168.100.10) +$ echo '{"method":"POST","headers":{"User-Agent":"Droonga Client"},"path":"/droonga/add","body":{"key":"id1","values":{"name":"Adam","age":20}}}' | + droonga-send --server http:192.168.100.50:10041 --report-request +Request: { + "method": "POST", + "path": "/droonga/add", + "headers": { + "User-Agent": "Droonga Client", + "Accept": "*/*" + }, + "body": "{\"key\":\"id1\",\"values\":{\"name\":\"Adam\",\"age\":20}}" +} +~~~ + + +## パラメータ {#parameters} + + +`--server=PROTOCOL:HOST:PORT/TAG` +: Droongaクラスタの接続先として使うプロトコル、ホスト名、ポート番号、タグ名。 + このオプションは複数回指定できます。 + 既定の状態では、`(--default-protocolによる既定のプロトコル):(このコマンドを実行しているコンピュータの推測された名前):(--default-portによる既定のポート番号)/(--default-tagによる既定のタグ名)`が1つだけ指定されたものとして扱われます。 + +`--messages-per-second=N` +: 1秒間に送るメッセージの最大数。 + `-1`を指定した場合、"無制限"を意味します。 + 既定値は`100`です。 + +`--default-protocol=PROTOCOL` +: Droongaクラスタの接続先との通信に使う既定のプロトコル。 + 取り得る値は以下の通りです: + + * `droonga` (既定値): Droonga Engineノードのネイティブプロトコル。 + * `http`: HTTP。 + +`--default-port=PORT` +: Droongaクラスタの接続先との通信に使う既定のポート番号。 + 既定値は`10031`です。 + +`--default-tag=TAG` +: Droongaクラスタの接続先との通信に使う既定のタグ名。 + 既定値は`droonga`です。 + +`--[no-]report-request` +: 実際に送信されたリクエストのメッセージを報告するかどうか。 + 既定の状態は、`--no-report-request`が指定されている場合に等しいです。 + 実際に送られたメッセージを見るためには、`--report-request`オプションを手動で指定する必要があります。 + +`--[no-]report-throughput` +: 1秒あたりのメッセージのスループットを報告するかどうか。 + 既定の状態は、`--no-report-throughput`が指定されている場合に等しいです。 + スループットを報告するには、`--report-throughput`オプションを手動で指定する必要があります。 + +`--default-dataset=NAME` +: メッセージの既定の送信先データセット名。 + 既定値は`Default`です。 + +`--default-target-role=ROLE` +: メッセージを処理できるEngineノードの既定のロール。 + 以下のいずれかを指定します: + + * `service-provider`: + メッセージは、クラスタ内でサービスを提供中のノードで処理されます。 + データ抽出操作に関わるノードには、後から遅れてメッセージが伝搬します。 + * `absorb-source`: + メッセージは、クラスタへのノード追加操作におけるデータコピー元となっているノードで処理されます。 + サービスを提供中のノード、並びにデータコピー先となっているノードへは、メッセージは伝搬しません。 + * `absorb-destination`: + メッセージは、クラスタへのノード追加操作におけるデータコピー先となっているノードで処理されます。 + サービスを提供中のノード、並びにデータコピー元となっているノードへは、メッセージは伝搬しません。 + * `any`: + メッセージは、`--host`で指定されたノードで処理されます。 + + 既定値は`any`です。 + +`--[no-]completion` +: 入力メッセージの必須フィールドを補完するかどうか。 + 既定の状態は、`--completion`が指定されている場合に等しいです。 + (既定のフィールドが欠落した)壊れたメッセージを意図的に送りたい場合は、`--no-completion`オプションを手動で指定する必要があります。 + +`--[no-]validation` +: 入力メッセージの妥当性を検証するかどうか。 + 既定の状態は、`--validation`が指定されている場合に等しいです。 + 妥当でない内容のメッセージを意図的に送りたい場合は、`--no-validation`オプションを手動で指定する必要があります。 + +`--help` +: コマンドの使い方の説明を表示します。 + + + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-client`の一部としてインストールされます。 + +~~~ +# gem install droonga-client +~~~ + Added: ja/reference/1.1.2/command-line-tools/droonga-system-status/index.md (+132 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/droonga-system-status/index.md 2015-11-15 23:29:56 +0900 (9e0af31) @@ -0,0 +1,132 @@ +--- +title: droonga-system-status +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/droonga-system-status/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`droonga-system-status`は、Droongaクラスタの現在の状態を報告します。 + +例えば、`192.168.100.50`というDroonga Engineノードがあり、同一ネットワークセグメント内のコンピュータ`192.168.100.10`にログインしている場合、クラスタの状態を報告するコマンド列は以下のようになります: + +~~~ +(on 192.168.100.10) +$ droonga-system-status --host 192.168.100.50 --receiver-host 192.168.100.10 --pretty +{ + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "node0:55329/droonga @ node0:10031/droonga" +} +~~~ + +このコマンドは、typeが[`system.status`](../../commands/system/status/)であるメッセージを[`droonga-request`](../droonga-request/)を用いて送信する操作を簡単に行う物です。 +上記コマンド列によってもたらされる結果は、以下のコマンド列の結果と実質的に同一です: + +~~~ +(on 192.168.100.10) +$ echo '{"type":"system.status"}' | + droonga-request --report-request --host 192.168.100.50 --receiver-host 192.168.100.10 +Request: { + "type": "system.status", + "id": "1430963525.9829412", + "date": "2015-05-07T02:39:50.334377Z", + "dataset": "Default" +} +Elapsed time: 0.00900742 +{ + "inReplyTo": "1430963525.9829412", + "statusCode": 200, + "type": "system.status.result", + "body": { + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "node0:55329/droonga @ node0:10031/droonga" + } +} +~~~ + +[`system.status`コマンドのリファレンス](../../commands/system/status/)も併せて参照して下さい。 + +## パラメータ {#parameters} + +`--pretty` +: 結果をpretty print形式のJSONで出力します。 + +`--host=NAME` +: メッセージの送信先となるEngineノードのホスト名。 + 既定値は、コマンドを実行しているコンピュータ自身の推測されたホスト名です。 + +`--port=PORT` +: Engineノードとの通信に使うポート番号。 + 既定値は`10031`です。 + +`--tag=TAG` +: Engineノードとの通信に使うタグ名。 + 既定値は`droonga`です。 + +`--dataset=NAME` +: メッセージの送信先データセット名。 + 既定値は`Default`です。 + +`--receiver-host=NAME` +: このコマンドを実行しているコンピュータのホスト名。 + 既定値は、そのコンピュータのホスト名として推測される名前です。 + +`--target-role=ROLE` +: メッセージを処理できるEngineノードのロール。 + 以下のいずれかを指定します: + + * `service-provider`: + メッセージは、クラスタ内でサービスを提供中のノードで処理されます。 + データ抽出操作に関わるノードには、後から遅れてメッセージが伝搬します。 + * `absorb-source`: + メッセージは、クラスタへのノード追加操作におけるデータコピー元となっているノードで処理されます。 + サービスを提供中のノード、並びにデータコピー先となっているノードへは、メッセージは伝搬しません。 + * `absorb-destination`: + メッセージは、クラスタへのノード追加操作におけるデータコピー先となっているノードで処理されます。 + サービスを提供中のノード、並びにデータコピー元となっているノードへは、メッセージは伝搬しません。 + * `any`: + メッセージは、`--host`で指定されたノードで処理されます。 + + 既定値は`any`です。 + +`--timeout=SECONDS` +: 応答がない接続を打ち切るまでの待ち時間(単位:秒)です。 + 既定値は`3`です。 + +`-h`, `--help` +: コマンドの使い方の説明を表示します。 + + +## インストール方法 {#install} + +このコマンドは、Rubygemsのパッケージ`droonga-client`の一部としてインストールされます。 + +~~~ +# gem install droonga-client +~~~ + Added: ja/reference/1.1.2/command-line-tools/index.md (+40 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/command-line-tools/index.md 2015-11-15 23:29:56 +0900 (0cda4b9) @@ -0,0 +1,40 @@ +--- +title: コマンドラインツール +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/command-line-tools/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +Droongaはいくつかのコマンドラインツールを提供しています。 +このセクションでは、それらの使い方を説明しています。 + +## Droongaクラスタとの通信 + + * [droonga-add](droonga-add/): クラスタに新しいレコードを追加します。 + * [droonga-groonga](droonga-groonga/): クラスタにGroongaコマンドを送信します。 + * [droonga-system-status](droonga-system-status/): クラスタ内のメンバーの状態を出力します。 + * [droonga-request](droonga-request/): 任意のメッセージをクラスタに送信し、レスポンスを出力します。 + * [droonga-send](droonga-send/): 任意のメッセージをクラスタに送信します。 + * [drndump](drndump/): クラスタから全てのスキーマ定義およびレコードの情報を抽出します。 + +## クラスタの管理 + + * [droonga-engine-join](droonga-engine-join/): クラスタに新しいreplicaを追加します。 + * [droonga-engine-unjoin](droonga-engine-unjoin/): クラスタから既存のreplicaを削除します。 + * [droonga-engine-absorb-data](droonga-engine-absorb-data/): クラスタ間で全てのスキーマ定義およびレコードの情報をコピーします。 + * [droonga-engine-set-role](droonga-engine-set-role/): クラスタ内のノードのroleを設定します。 + +## 低レイヤのシステム管理 + + * [droonga-engine-configure](droonga-engine-configure/): コンピュータ上の`droonga-engine`サービスを設定します。 + * [droonga-engine-catalog-generate](droonga-engine-catalog-generate/): クラスタ定義ファイルを新たに生成します。 + * [droonga-engine-catalog-modify](droonga-engine-catalog-modify/): 既存のクラスタ定義ファイルを更新します。 + * [droonga-http-server-configure](droonga-http-server-configure/): コンピュータ上の`droonga-http-server`サービスを設定します。 + Added: ja/reference/1.1.2/commands/add/index.md (+262 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/add/index.md 2015-11-15 23:29:56 +0900 (5d16b61) @@ -0,0 +1,262 @@ +--- +title: add +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/add/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`add` は、テーブルにレコードを登録します。対象のテーブルが主キーを持っており、同じキーのレコードが既に存在している場合には、既存レコードのカラムの値を更新します。 + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/droonga/add` + +リクエストメソッド +: `POST` + +リクエストのURLパラメータ +: なし。 + +リクエストのbody +: [パラメータ](#parameters)のハッシュ。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `add` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `add.result` + +## パラメータの構文 {#syntax} + +対象のテーブルが主キーを持つ場合: + + { + "table" : "<テーブル名>", + "key" : "<レコードの主キー>", + "values" : { + "<カラム1の名前>" : <値1>, + "<カラム2の名前>" : <値2>, + ... + } + } + +対象のテーブルが主キーを持たない場合: + + { + "table" : "<テーブル名>", + "values" : { + "<カラム1の名前>" : <値1>, + "<カラム2の名前>" : <値2>, + ... + } + } + +## 使い方 {#usage} + +本項の説明では以下のような2つのテーブルが存在している事を前提として、典型的な使い方を通じて `add` コマンドの使い方を説明します。 + +Personテーブル(主キー無し): + +|name|job (Jobテーブルを参照)| +|Alice Arnold|announcer| +|Alice Cooper|musician| + +Jobテーブル(主キー有り): + +|_key|label| +|announcer|announcer| +|musician|musician| + + +### 主キーを持たないテーブルにレコードを追加する {#adding-record-to-table-without-key} + +主キーを持たないテーブルにレコードを追加する場合は、 `key` を指定せずに `table` と `values` だけを指定します。 + + { + "type" : "add", + "body" : { + "table" : "Person", + "values" : { + "name" : "Bob Dylan", + "job" : "musician" + } + } + } + + => { + "type" : "add.result", + "body" : true + } + +`add` は再帰的に動作します。別のテーブルを参照しているカラムについて、参照先のテーブルに存在しない値を指定した場合、エラーにはならず、参照先のテーブルにも同時に新しいレコードが追加されます。例えば、以下は テーブルに存在しない主キー `doctor` を伴って Person テーブルにレコードを追加します。 + + { + "type" : "add", + "body" : { + "table" : "Person", + "values" : { + "name" : "Alice Miller", + "job" : "doctor" + } + } + } + + => { + "type" : "add.result", + "body" : true + } + +この時、Jobテーブルには主キーだけが指定された新しいレコードが自動的に追加されます。 + +|_key|label| +|announcer|announcer| +|musician|musician| +|doctor|(空文字)| + + +### 主キーを持つテーブルにレコードを追加する {#adding-record-to-table-with-key} + +主キーを持つテーブルにレコードを追加する場合は、 `table`、`key`、`values` のすべてを指定します。 + + { + "type" : "add", + "body" : { + "table" : "Job", + "key" : "writer", + "values" : { + "label" : "writer" + } + } + } + + => { + "type" : "add.result", + "body" : true + } + +### 既存レコードのカラムの値を更新する {#updating} + +主キーを持つテーブルに対する、既存レコードの主キーを伴う `add` コマンドは、既存レコードのカラムの値の更新操作と見なされます。 + + { + "type" : "add", + "body" : { + "table" : "Job", + "key" : "doctor", + "values" : { + "label" : "doctor" + } + } + } + + => { + "type" : "add.result", + "body" : true + } + + +主キーを持たないテーブルのレコードに対しては、値の更新操作はできません(常にレコードの追加と見なされます)。 + + +## パラメータの詳細 {#parameters} + +### `table` {#parameter-table} + +概要 +: レコードを登録するテーブルの名前を指定します。 + +値 +: テーブル名の文字列。 + +省略時の既定値 +: なし。このパラメータは必須です。 + +### `key` {#parameter-key} + +概要 +: レコードの主キーを指定します。 + +値 +: 主キーとなる文字列。 + +省略時の初期値 +: Nなし。対象のテーブルが主キーを持つ場合、このパラメータは必須です。主キーがない場合、このパラメータは無視されます。 + +既に同じ主キーを持つレコードが存在している場合は、レコードの各カラムの値を更新します。 + +対象のテーブルが主キーを持たない場合は、指定しても単に無視されます。 + +### `values` {#parameter-values} + +概要 +: レコードの各カラムの値を指定します。 + +値 +: カラム名をキー、カラムの値を値としたハッシュ。 + +省略時の初期値 +: `null` + +指定されなかったカラムの値は登録・更新されません。 + + +## レスポンス {#response} + +このコマンドは、レコードを正常に追加または更新できた場合、真偽値 `true` を`body` 、`200` を `statusCode` としたレスポンスを返します。以下はレスポンスの `body` の例です。 + + true + +## エラーの種類 {#errors} + +このコマンドは[一般的なエラー](/ja/reference/message/#error)に加えて、以下のエラーを場合に応じて返します。 + +### `MissingTableParameter` + +`table` パラメータの指定を忘れていることを示します。ステータスコードは `400` です。 + +### `MissingPrimaryKeyParameter` + +主キーが存在するテーブルに対して、`key` パラメータの指定を忘れていることを示します。ステータスコードは `400` です。 + +### `InvalidValue` + +カラムに設定しようとした値が不正である(例:位置情報型や整数型のカラムに通常の文字列を指定した、など)事を示します。ステータスコードは `400` です。 + +### `UnknownTable` + +指定されたデータセット内に、指定されたレコードが存在していない事を示します。ステータスコードは `404` です。 + +### `UnknownColumn` + +指定されたカラムがテーブルに存在しない未知のカラムである事を示します。ステータスコードは `400` です。 + Added: ja/reference/1.1.2/commands/column-create/index.md (+110 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/column-create/index.md 2015-11-15 23:29:56 +0900 (fb7e2db) @@ -0,0 +1,110 @@ +--- +title: column_create +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/column-create/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`column_create` は、指定したテーブルに新しいカラムを作成します。 + +このコマンドは[Groonga の `column_create` コマンド](http://groonga.org/ja/docs/reference/commands/column_create.html)と互換性があります。 + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/d/column_create` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの一覧](#parameters)で定義されている物を指定します。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `column_create` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `column_create.result` + +## パラメータの構文 {#syntax} + + { + "table" : "<テーブル名>", + "name" : "<カラム名>", + "flags" : "<カラムの属性>", + "type" : "<値の型>", + "source" : "<インデックス対象のカラム名>" + } + +## パラメータの詳細 {#parameters} + +`table`, `name` 以外のパラメータはすべて省略可能です。 + +すべてのパラメータは[Groonga の `column_create` コマンドの引数](http://groonga.org/ja/docs/reference/commands/column_create.html#parameters)と共通です。詳細はGroongaのコマンドリファレンスを参照して下さい。 + +## レスポンス {#response} + +このコマンドは、レスポンスの `body` としてコマンドの実行結果に関する情報を格納した配列を返却します。 + + [ + [ + <Groongaのステータスコード>, + <開始時刻>, + <処理に要した時間> + ], + <カラムが作成されたかどうか> + ] + +このコマンドはレスポンスの `statusCode` として常に `200` を返します。これは、Groonga互換コマンドのエラー情報はGroongaのそれと同じ形で処理される必要があるためです。 + +レスポンスの `body` の詳細: + +ステータスコード +: コマンドが正常に受け付けられたかどうかを示す整数値です。以下のいずれかの値をとります。 + + * `0` (`Droonga::GroongaHandler::Status::SUCCESS`) : 正常に処理された。. + * `-22` (`Droonga::GroongaHandler::Status::INVALID_ARGUMENT`) : 引数が不正である。 + +開始時刻 +: 処理を開始した時刻を示す数値(UNIX秒)。 + +処理に要した時間 +: 処理を開始してから完了までの間にかかった時間を示す数値。 + +カラムが作成されたかどうか +: カラムが作成されたかどうかを示す真偽値です。以下のいずれかの値をとります。 + + * `true`:カラムを作成した。 + * `false`:カラムを作成しなかった。 Added: ja/reference/1.1.2/commands/column-list/index.md (+103 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/column-list/index.md 2015-11-15 23:29:56 +0900 (614096b) @@ -0,0 +1,103 @@ +--- +title: column_list +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/column-list/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +The `column_list` command reports the list of all existing columns in a table. + +This is compatible to [the `column_list` command of the Groonga](http://groonga.org/docs/reference/commands/column_list.html). + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/d/column_list` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの一覧](#parameters)で定義されている物を指定します。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `column_list` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `column_list.result` + +## パラメータの構文 {#syntax} + + { + "table" : "<Name of the table>" + } + +## パラメータの詳細 {#parameters} + +The only one parameter `table` is required. + +They are compatible to [the parameters of the `column_list` command of the Groonga](http://groonga.org/docs/reference/commands/column_list.html#parameters). See the linked document for more details. + +## レスポンス {#response} + +このコマンドは、レスポンスの `body` としてコマンドの実行結果に関する情報を格納した配列を返却します。 + + [ + [ + <Groonga's status code>, + <Start time>, + <Elapsed time> + ], + <List of columns> + ] + +The structure of the returned array is compatible to [the returned value of the Groonga's `table_list` command](http://groonga.org/docs/reference/commands/column_list.html#return-value). See the linked document for more details. + +このコマンドはレスポンスの `statusCode` として常に `200` を返します。これは、Groonga互換コマンドのエラー情報はGroongaのそれと同じ形で処理される必要があるためです。 + +レスポンスの `body` の詳細: + +ステータスコード +: コマンドが正常に受け付けられたかどうかを示す整数値です。以下のいずれかの値をとります。 + + * `0` (`Droonga::GroongaHandler::Status::SUCCESS`) : 正常に処理された。. + * `-22` (`Droonga::GroongaHandler::Status::INVALID_ARGUMENT`) : 引数が不正である。 + +開始時刻 +: 処理を開始した時刻を示す数値(UNIX秒)。 + +処理に要した時間 +: 処理を開始してから完了までの間にかかった時間を示す数値。 + Added: ja/reference/1.1.2/commands/column-remove/index.md (+107 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/column-remove/index.md 2015-11-15 23:29:56 +0900 (8d7d7a1) @@ -0,0 +1,107 @@ +--- +title: column_remove +layout: en +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/column-remove/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +The `column_remove` command removes an existing column in a table. + +This is compatible to [the `column_remove` command of the Groonga](http://groonga.org/docs/reference/commands/column_remove.html). + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/d/column_remove` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの一覧](#parameters)で定義されている物を指定します。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `column_remove` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `column_remove.result` + +## パラメータの構文 {#syntax} + + { + "table" : "<Name of the table>", + "name" : "<Name of the column>" + } + +## パラメータの詳細 {#parameters} + +All parameters are required. + +They are compatible to [the parameters of the `column_remove` command of the Groonga](http://groonga.org/docs/reference/commands/column_remove.html#parameters). See the linked document for more details. + +## レスポンス {#response} + +このコマンドは、レスポンスの `body` としてコマンドの実行結果に関する情報を格納した配列を返却します。 + + [ + [ + <Groonga's status code>, + <Start time>, + <Elapsed time> + ], + <Column is successfully removed or not> + ] + +このコマンドはレスポンスの `statusCode` として常に `200` を返します。これは、Groonga互換コマンドのエラー情報はGroongaのそれと同じ形で処理される必要があるためです。 + +レスポンスの `body` の詳細: + +ステータスコード +: コマンドが正常に受け付けられたかどうかを示す整数値です。以下のいずれかの値をとります。 + + * `0` (`Droonga::GroongaHandler::Status::SUCCESS`) : 正常に処理された。. + * `-22` (`Droonga::GroongaHandler::Status::INVALID_ARGUMENT`) : 引数が不正である。 + +開始時刻 +: 処理を開始した時刻を示す数値(UNIX秒)。 + +処理に要した時間 +: 処理を開始してから完了までの間にかかった時間を示す数値。 + +Column is successfully removed or not +: A boolean value meaning the column was successfully removed or not. Possible values are: + + * `true`:The column was successfully removed. + * `false`:The column was not removed. Added: ja/reference/1.1.2/commands/column-rename/index.md (+108 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/column-rename/index.md 2015-11-15 23:29:56 +0900 (9110de3) @@ -0,0 +1,108 @@ +--- +title: column_rename +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/column-rename/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +The `column_rename` command renames an existing column in a table. + +This is compatible to [the `column_rename` command of the Groonga](http://groonga.org/docs/reference/commands/column_rename.html). + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/d/column_rename` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの一覧](#parameters)で定義されている物を指定します。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `column_rename` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `column_rename.result` + +## パラメータの構文 {#syntax} + + { + "table" : "<Name of the table>", + "name" : "<Current name of the column>", + "new_name" : "<New name of the column>" + } + +## パラメータの詳細 {#parameters} + +All parameters are required. + +They are compatible to [the parameters of the `column_rename` command of the Groonga](http://groonga.org/docs/reference/commands/column_rename.html#parameters). See the linked document for more details. + +## レスポンス {#response} + +このコマンドは、レスポンスの `body` としてコマンドの実行結果に関する情報を格納した配列を返却します。 + + [ + [ + <Groonga's status code>, + <Start time>, + <Elapsed time> + ], + <Column is successfully renamed or not> + ] + +このコマンドはレスポンスの `statusCode` として常に `200` を返します。これは、Groonga互換コマンドのエラー情報はGroongaのそれと同じ形で処理される必要があるためです。 + +レスポンスの `body` の詳細: + +ステータスコード +: コマンドが正常に受け付けられたかどうかを示す整数値です。以下のいずれかの値をとります。 + + * `0` (`Droonga::GroongaHandler::Status::SUCCESS`) : 正常に処理された。. + * `-22` (`Droonga::GroongaHandler::Status::INVALID_ARGUMENT`) : 引数が不正である。 + +開始時刻 +: 処理を開始した時刻を示す数値(UNIX秒)。 + +処理に要した時間 +: 処理を開始してから完了までの間にかかった時間を示す数値。 + +Column is successfully renamed or not +: A boolean value meaning the column was successfully renamed or not. Possible values are: + + * `true`:The column was successfully renamed. + * `false`:The column was not renamed. Added: ja/reference/1.1.2/commands/delete/index.md (+122 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/delete/index.md 2015-11-15 23:29:56 +0900 (0c93f95) @@ -0,0 +1,122 @@ +--- +title: delete +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/delete/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +The `delete` command removes records in a table. + +This is compatible to [the `delete` command of the Groonga](http://groonga.org/docs/reference/commands/delete.html). + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/d/delete` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの一覧](#parameters)で定義されている物を指定します。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `delete` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `delete.result` + +## パラメータの構文 {#syntax} + + { + "table" : "<Name of the table>", + "key" : "<Key of the record>" + } + +または + + { + "table" : "<Name of the table>", + "id" : "<ID of the record>" + } + +または + + { + "table" : "<Name of the table>", + "filter" : "<Complex search conditions>" + } + +## パラメータの詳細 {#parameters} + +All parameters except `table` are optional. +However, you must specify one of `key`, `id`, or `filter` to specify the record (records) to be removed. + +They are compatible to [the parameters of the `delete` command of the Groonga](http://groonga.org/docs/reference/commands/delete.html#parameters). See the linked document for more details. + +## レスポンス {#response} + +このコマンドは、レスポンスの `body` としてコマンドの実行結果に関する情報を格納した配列を返却します。 + + [ + [ + <Groonga's status code>, + <Start time>, + <Elapsed time> + ], + <Records are successfully removed or not> + ] + +このコマンドはレスポンスの `statusCode` として常に `200` を返します。これは、Groonga互換コマンドのエラー情報はGroongaのそれと同じ形で処理される必要があるためです。 + +レスポンスの `body` の詳細: + +ステータスコード +: コマンドが正常に受け付けられたかどうかを示す整数値です。以下のいずれかの値をとります。 + + * `0` (`Droonga::GroongaHandler::Status::SUCCESS`) : 正常に処理された。. + * `-22` (`Droonga::GroongaHandler::Status::INVALID_ARGUMENT`) : 引数が不正である。 + +開始時刻 +: 処理を開始した時刻を示す数値(UNIX秒)。 + +処理に要した時間 +: 処理を開始してから完了までの間にかかった時間を示す数値。 + +Records are successfully removed or not +: A boolean value meaning specified records were successfully removed or not. Possible values are: + + * `true`:Records were successfully removed. + * `false`:Records were not removed. Added: ja/reference/1.1.2/commands/index.md (+35 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/index.md 2015-11-15 23:29:56 +0900 (9e16e08) @@ -0,0 +1,35 @@ +--- +title: コマンドリファレンス +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +以下のコマンドを利用できます。 + +## ビルトインのコマンド + + * [search](search/): データの検索 + * [add](add/): レコードの追加 + * system: クラスタのシステム情報の取得 + * [system.status](system/status/): クラスタのステータス情報の取得 + +## Groonga互換コマンド + + * [column_create](column-create/) + * [column_list](column-list/) + * [column_remove](column-remove/) + * [column_rename](column-rename/) + * [delete](delete/) + * [load](load/) + * [select](select/) + * [table_create](table-create/) + * [table_list](table-list/) + * [table_remove](table-remove/) Added: ja/reference/1.1.2/commands/load/index.md (+125 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/load/index.md 2015-11-15 23:29:56 +0900 (5f1e186) @@ -0,0 +1,125 @@ +--- +title: load +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/load/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +The `load` command adds new records to the specified table. +Column values of existing records are updated by new values, if the table has a primary key and there are existing records with specified keys. + +This is compatible to [the `load` command of the Groonga](http://groonga.org/docs/reference/commands/load.html). + +## APIの形式 {#api-types} + +### HTTP (GET) {#api-types-http-get} + +リクエスト先 +: `(ドキュメントルート)/d/load` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの一覧](#parameters)で定義されている物を指定します。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### HTTP (POST) {#api-types-http-post} + +リクエスト先 +: `(ドキュメントルート)/d/load` + +リクエストメソッド +: `POST` + +リクエストのURLパラメータ +: [パラメータの一覧](#parameters)で定義されている物のうち、`values` 以外を指定します。 + +リクエストのbody +: [パラメータ](#parameters)の `values` 用の値を指定します。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +対応していません。 + +## パラメータの構文 {#syntax} + + { + "values" : <Array of records to be loaded>, + "table" : "<Name of the table>", + "columns" : "<List of column names for values, separated by ','>", + "ifexists" : "<Grn_expr to determine records which should be updated>", + "input_type" : "<Format type of the values>" + } + +## パラメータの詳細 {#parameters} + +`table` 以外のパラメータはすべて省略可能です。 + +また、バージョン {{ site.droonga_version }} の時点では以下のパラメータのみが動作します。これら以外のパラメータは未実装のため無視されます。 + + * `values` + * `table` + * `columns` + +They are compatible to [the parameters of the `load` command of the Groonga](http://groonga.org/docs/reference/commands/load.html#parameters). See the linked document for more details. + +HTTP clients can send `values` as an URL parameter with `GET` method, or the request body with `POST` method. +The URL parameter `values` is always ignored it it is sent with `POST` method. +You should send data with `POST` method if there is much data. + +## レスポンス {#response} + +このコマンドは、レスポンスの `body` としてコマンドの実行結果に関する情報を格納した配列を返却します。 + + [ + [ + <Groonga's status code>, + <Start time>, + <Elapsed time> + ], + [<Number of loaded records>] + ] + +このコマンドはレスポンスの `statusCode` として常に `200` を返します。これは、Groonga互換コマンドのエラー情報はGroongaのそれと同じ形で処理される必要があるためです。 + +レスポンスの `body` の詳細: + +ステータスコード +: コマンドが正常に受け付けられたかどうかを示す整数値です。以下のいずれかの値をとります。 + + * `0` (`Droonga::GroongaHandler::Status::SUCCESS`) : 正常に処理された。. + * `-22` (`Droonga::GroongaHandler::Status::INVALID_ARGUMENT`) : 引数が不正である。 + +開始時刻 +: 処理を開始した時刻を示す数値(UNIX秒)。 + +処理に要した時間 +: 処理を開始してから完了までの間にかかった時間を示す数値。 + +Number of loaded records +: An positive integer meaning the number of added or updated records. Added: ja/reference/1.1.2/commands/search/index.md (+1382 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/search/index.md 2015-11-15 23:29:56 +0900 (83beda3) @@ -0,0 +1,1382 @@ +--- +title: search +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/search/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`search` は、1つ以上のテーブルから指定された条件にマッチするレコードを検索し、見つかったレコードに関する情報を返却します。 + +これは、Droonga において検索機能を提供する最も低レベルのコマンドです。 +検索用のコマンドをプラグインとして実装する際は、内部的にこのコマンドを使用して検索を行うという用途が想定されます。 + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/droonga/search` + +リクエストメソッド +: `POST` + +リクエストのURLパラメータ +: なし。 + +リクエストのbody +: [パラメータ](#parameters)のハッシュ。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +リクエスト先 +: `(ドキュメントルート)/tables/(テーブル名)` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [検索リクエストのパラメータ](#parameters)に対応する以下のパラメータを受け付けます: + + * `query`: [`(root).(テーブル名).condition.query`](#usage-condition-query-syntax) に対応する文字列。 + * `match_to`: [`(root).(テーブル名).condition.matchTo`](#usage-condition-query-syntax) に対応するカンマ区切りの文字列。 + * `sort_by`: [`(root).(テーブル名).sortBy`](#query-sortBy) に対応するカンマ区切りの文字列。 + * `attributes`: [`(root).(テーブル名).output.attributes`](#query-output) に対応するカンマ区切りの文字列。 + * `offset`: [`(root).(テーブル名).output.offset`](#query-output) に対応する整数。 + * `limit`: [`(root).(テーブル名).output.limit`](#query-output) に対応する整数。 + * `timeout`: [`(root).timeout`](#parameter-timeout) に対応する整数。 + +<!-- + * `group_by[(column name)][key]`: A string, applied to [`(root).(column name).groupBy.key`](#query-groupBy). + * `group_by[(column name)][max_n_sub_records]`: An integer, applied to [`(root).(column name).groupBy.maxNSubRecords`](#query-groupBy). + * `group_by[(column name)][attributes]`: A comma-separated string, applied to [`(root).(column name).output.attributes`](#query-output). + * `group_by[(column name)][attributes][(attribute name)][source]`: A string, applied to [`(root).(column name).output.attributes.(attribute name).source`](#query-output). + * `group_by[(column name)][attributes][(attribute name)][attributes]`: A comma-separated string, applied to [`(root).(column name).output.attributes.(attribute name).attributes`](#query-output). + * `group_by[(column name)][limit]`: An integer, applied to [`(root).(column name).output.limit`](#query-output). +--> + + 例: + + * `/tables/Store?query=NY&match_to=_key&attributes=_key,*&limit=10` + +<!-- + * `/tables/Store?query=NY&match_to=_key&attributes=_key,*&limit=10&group_by[location][key]=location&group_by[location][limit]=5&group_by[location][attributes]=_key,_nsubrecs` + * `/tables/Store?query=NY&match_to=_key&attributes=_key,*&limit=10&group_by[location][key]=location&group_by[location][limit]=5&group_by[location][attributes][_key][souce]=_key&group_by[location][attributes][_nsubrecs][souce]=_nsubrecs` + * `/tables/Store?query=NY&match_to=_key&limit=0&group_by[location][key]=location&group_by[location][max_n_sub_records]=5&group_by[location][limit]=5&group_by[location][attributes][sub_records][source]=_subrecs&group_by[location][attributes][sub_records][attributes]=_key,location` +--> + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `search` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `search.result` + +## パラメータの構文 {#syntax} + + { + "timeout" : <タイムアウトするまでの秒数>, + "queries" : { + "<クエリ1の名前>" : { + "source" : "<検索対象のテーブル名、または別の検索クエリの名前>", + "condition" : <検索条件>, + "sortBy" : <ソートの条件>, + "groupBy" : <集約の条件>, + "output" : <出力の指定> + }, + "<クエリ2の名前>" : { ... }, + ... + } + } + +## 使い方 {#usage} + +この項では、以下のテーブルが存在する状態を前提として、典型的な使い方を通じて `search` コマンドの使い方を説明します。 + +Personテーブル(主キーあり): + +|_key|name|age|sex|job|note| +|Alice Arnold|Alice Arnold|20|female|announcer|| +|Alice Cooper|Alice Cooper|30|male|musician|| +|Alice Miller|Alice Miller|25|female|doctor|| +|Bob Dole|Bob Dole|42|male|lawer|| +|Bob Cousy|Bob Cousy|38|male|basketball player|| +|Bob Wolcott|Bob Wolcott|36|male|baseball player|| +|Bob Evans|Bob Evans|31|male|driver|| +|Bob Ross|Bob Ross|54|male|painter|| +|Lewis Carroll|Lewis Carroll|66|male|writer|the author of Alice's Adventures in Wonderland| + +※`name`、`note` には `TokensBigram` を使用したインデックスが用意されていると仮定します。 + +### 基本的な使い方 {#usage-basic} + +最も単純な例として、Person テーブルのすべてのレコードを出力する例を示します。 + + { + "type" : "search", + "body" : { + "queries" : { + "people" : { + "source" : "Person", + "output" : { + "elements" : ["count", "records"], + "attributes" : ["_key", "*"], + "limit" : -1 + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "people" : { + "count" : 9, + "records" : [ + ["Alice Arnold", "Alice Arnold", 20, "female", "announcer", ""], + ["Alice Cooper", "Alice Cooper", 30, "male", "musician", ""], + ["Alice Miller", "Alice Miller", 25, "male", "doctor", ""], + ["Bob Dole", "Bob Dole", 42, "male", "lawer", ""], + ["Bob Cousy", "Bob Cousy", 38, "male", "basketball player", ""], + ["Bob Wolcott", "Bob Wolcott", 36, "male", "baseball player", ""], + ["Bob Evans", "Bob Evans", 31, "male", "driver", ""], + ["Bob Ross", "Bob Ross", 54, "male", "painter", ""], + ["Lewis Carroll", "Lewis Carroll", 66, "male", "writer", + "the author of Alice's Adventures in Wonderland"] + ] + } + } + } + +`people` は、この検索クエリおよびその処理結果に対して付けた一時的な名前です。 +`search` のレスポンスは、検索クエリに付けた名前を伴って返されます。 +よって、これは「この検索クエリの結果を `people` と呼ぶ」というような意味合いになります。 + +どうしてこのコマンドが全レコードのすべての情報を出力するのでしょうか? これは以下の理由に依ります。 + + * 検索条件を何も指定していないため。検索条件を指定しないとすべてのレコードがマッチします。 + * [`output`](#query-output) の `elements` パラメータに `records` (および `count`)が指定されているため。 `elements` は結果に出力する情報を制御します。マッチしたレコードの情報は `records` に、マッチしたレコードの総数は `count` に出力されます。 + * [`output`](#query-output) の `limit` パラメータに `-1` が指定されているため。 `limit` は出力するレコードの最大数の指定ですが、 `-1` を指定するとすべてのレコードが出力されます。 + * [`output`](#query-output) の `attributes` パラメータに `"_key"` と `"*"` の2つが指定されているため(これは「`_key` を含む Person テーブルのすべてのカラムを出力する」という指定で、`["_key", "name", "age", "sex", "job", "note"]` と書くのに等しいです)。 `attributes` は個々のレコードに出力するカラムを制御します。 + + +#### 検索条件 {#usage-condition} + +検索条件は `condition` パラメータで指定します。指定方法は、大きく分けて「スクリプト構文形式」と「クエリー構文形式」の2通りがあります。詳細は [`condition` パラメータの仕様](#query-condition) を参照して下さい。 + +##### スクリプト構文形式の検索条件 {#usage-condition-script-syntax} + +スクリプト構文形式は、ECMAScriptの書式に似ています。「`name` に `Alice` を含み、且つ`age` が `25` 以上である」という検索条件は、スクリプト構文形式で以下のように表現できます。 + + { + "type" : "search", + "body" : { + "queries" : { + "people" : { + "source" : "Person", + "condition" : "name @ 'Alice' && age >= 25" + "output" : { + "elements" : ["count", "records"], + "attributes" : ["name", "age"], + "limit" : -1 + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "people" : { + "count" : 2, + "records" : [ + ["Alice Arnold", 20], + ["Alice Cooper", 30], + ["Alice Miller", 25] + ] + } + } + } + +スクリプト構文の詳細な仕様は[Groonga のスクリプト構文のリファレンス](http://groonga.org/ja/docs/reference/grn_expr/script_syntax.html)を参照して下さい。 + +##### クエリー構文形式の検索条件 {#usage-condition-query-syntax} + +クエリー構文形式は、主にWebページなどに組み込む検索ボックス向けに用意されています。例えば「検索ボックスに入力された語句を `name` または `note` に含むレコードを検索する」という場面において、検索ボックスに入力された語句が `Alice` であった場合の検索条件は、クエリー構文形式で以下のように表現できます。 + + { + "type" : "search", + "body" : { + "queries" : { + "people" : { + "source" : "Person", + "condition" : { + "query" : "Alice", + "matchTo" : ["name", "note"] + }, + "output" : { + "elements" : ["count", "records"], + "attributes" : ["name", "note"], + "limit" : -1 + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "people" : { + "count" : 4, + "records" : [ + ["Alice Arnold", ""], + ["Alice Cooper", ""], + ["Alice Miller", ""], + ["Lewis Carroll", + "the author of Alice's Adventures in Wonderland"] + ] + } + } + } + +クエリー構文の詳細な仕様は[Groonga のクエリー構文のリファレンス](http://groonga.org/ja/docs/reference/grn_expr/query_syntax.html)を参照して下さい。 + + +#### 検索結果のソート {#usage-sort} + +出力するレコードのソート条件は `sortBy` パラメータで指定します。以下は、結果を `age` カラムの値の昇順でソートする場合の例です。 + + { + "type" : "search", + "body" : { + "queries" : { + "people" : { + "source" : "Person", + "condition" : "name @ 'Alice'" + "sortBy" : ["age"], + "output" : { + "elements" : ["count", "records"], + "attributes" : ["name", "age"], + "limit" : -1 + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "people" : { + "count" : 8, + "records" : [ + ["Alice Arnold", 20], + ["Alice Miller", 25], + ["Alice Cooper", 30] + ] + } + } + } + +ソートするカラム名の前に `-` を付けると、降順でのソートになります。以下は `age` の降順でソートする場合の例です。 + + { + "type" : "search", + "body" : { + "queries" : { + "people" : { + "source" : "Person", + "condition" : "name @ 'Alice'" + "sortBy" : ["-age"], + "output" : { + "elements" : ["count", "records"], + "attributes" : ["name", "age"], + "limit" : -1 + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "people" : { + "count" : 8, + "records" : [ + ["Alice Cooper", 30], + ["Alice Miller", 25], + ["Alice Arnold", 20] + ] + } + } + } + +詳細は [`sortBy` パラメータの仕様](#query-sortBy) を参照して下さい。 + +#### 検索結果のページング {#usage-paging} + +[`output`](#query-output) パラメータの `offset` と `limit` を指定することで、出力されるレコードの範囲を指定できます。以下は、20件以上ある結果を先頭から順に10件ずつ取得する場合の例です。 + + { + "type" : "search", + "body" : { + "queries" : { + "people" : { + "source" : "Person", + "output" : { + "elements" : ["count", "records"], + "attributes" : ["name"], + "offset" : 0, + "limit" : 10 + } + } + } + } + } + + => 0件目から9件目までの10件が返される。 + + { + "type" : "search", + "body" : { + "queries" : { + "people" : { + "source" : "Person", + "output" : { + "elements" : ["count", "records"], + "attributes" : ["name"], + "offset" : 10, + "limit" : 10 + } + } + } + } + } + + => 10件目から19件目までの10件が返される。 + + { + "type" : "search", + "body" : { + "queries" : { + "people" : { + "source" : "Person", + "output" : { + "elements" : ["count", "records"], + "attributes" : ["name"], + "offset" : 20, + "limit" : 10 + } + } + } + } + } + + => 20件目から29件目までの10件が返される。 + +`limit` の指定 `-1` は、実際の運用では推奨されません。膨大な量のレコードがマッチした場合、出力のための処理にリソースを使いすぎてしまいますし、ネットワークの帯域も浪費してしまいます。コンピュータの性能にもよりますが、`limit` には `100` 程度までの値を上限として指定し、それ以上のレコードは適宜ページングで取得するようにして下さい。 + +詳細は [`output` パラメータの仕様](#query-output) を参照して下さい。 + +また、ページングは [`sortBy` パラメータの機能](#query-sortBy-hash)でも行う事ができ、一般的にはそちらの方が高速に動作します。 +よって、可能な限り `output` でのページングよりも `sortBy` でのページングの方を使う事が推奨されます。 + + +#### 出力形式 {#usage-format} + +ここまでの例では、レコードの一覧はすべて配列の配列として出力されていました。[`output`](#query-output) パラメータの `format` を指定すると、出力されるレコードの形式を変える事ができます。以下は、`format` に `complex` を指定した場合の例です。 + + { + "type" : "search", + "body" : { + "queries" : { + "people" : { + "source" : "Person", + "output" : { + "elements" : ["count", "records"], + "attributes" : ["_key", "name", "age", "sex", "job", "note"], + "limit" : 3, + "format" : "complex" + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "people" : { + "count" : 9, + "records" : [ + { "_key" : "Alice Arnold", + "name" : "Alice Arnold", + "age" : 20, + "sex" : "female", + "job" : "announcer", + "note" : "" }, + { "_key" : "Alice Cooper", + "name" : "Alice Cooper", + "age" : 30, + "sex" : "male", + "job" : "musician", + "note" : "" }, + { "_key" : "Alice Miller", + "name" : "Alice Miller", + "age" : 25, + "sex" : "female", + "job" : "doctor", + "note" : "" } + ] + } + } + } + +`format` に `complex` を指定した場合、レコードの一覧はこの例のようにカラム名をキーとしたハッシュの配列として出力されます。 +`format` に `simple` を指定した場合、または `format` の指定を省略した場合、レコードの一覧は配列の配列として出力されます。 + +詳細は [`output` パラメータの仕様](#query-output) および [レスポンスの仕様](#response) を参照して下さい。 + + +### 高度な使い方 {#usage-advanced} + +#### 検索結果の集約 {#usage-group} + +[`groupBy`](#query-groupBy) パラメータを指定することで、レコードを指定カラムの値で集約した結果を取得することができます。以下は、テーブルの内容を `sex` カラムの値で集約した結果と、集約前のレコードがそれぞれ何件あったかを取得する例です。 + + { + "type" : "search", + "body" : { + "queries" : { + "sexuality" : { + "source" : "Person", + "groupBy" : "sex", + "output" : { + "elements" : ["count", "records"], + "attributes" : ["_key", "_nsubrecs"], + "limit" : -1 + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "sexuality" : { + "count" : 2, + "records" : + ["female", 2], + ["male", 7] + ] + } + } + } + +上記の結果は、 `sex` の値が `female` であるレコードが2件、`male` であるレコードが7件存在していて、`sex` の値の種類としては2通りが登録されている事を示しています。 + +また、集約前のレコードを代表値として取得する事もできます。以下は、`sex` カラムの値で集約した結果と、それぞれの集約前のレコードを2件ずつ取得する例です。 + + { + "type" : "search", + "body" : { + "queries" : { + "sexuality" : { + "source" : "Person", + "groupBy" : { + "keys" : "sex", + "maxNSubRecords" : 2 + }, + "output" : { + "elements" : ["count", "records"], + "attributes" : [ + "_key", + "_nsubrecs", + { "label" : "subrecords", + "source" : "_subrecs", + "attributes" : ["name"] } + ], + "limit" : -1 + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "sexuality" : { + "count" : 2, + "records" : + ["female", 2, [["Alice Arnold"], ["Alice Miller"]]], + ["male", 7, [["Alice Cooper"], ["Bob Dole"]]] + ] + } + } + } + + +詳細は [`groupBy` パラメータの仕様](#query-groupBy) を参照して下さい。 + + +#### 複数の検索クエリの列挙 {#usage-multiple-queries} + +`search` は、一度に複数の検索クエリを受け付ける事ができます。以下は、`age` が `25` 以下のレコードと `age` が `40` 以上のレコードを同時に検索する例です。 + + { + "type" : "search", + "body" : { + "queries" : { + "junior" : { + "source" : "Person", + "condition" : "age <= 25", + "output" : { + "elements" : ["count", "records"], + "attributes" : ["name", "age"], + "limit" : -1 + } + }, + "senior" : { + "source" : "Person", + "condition" : "age >= 40", + "output" : { + "elements" : ["count", "records"], + "attributes" : ["name", "age"], + "limit" : -1 + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "junior" : { + "count" : 2, + "records" : [ + ["Alice Arnold", 20], + ["Alice Miller", 25] + ] + }, + "senior" : { + "count" : 3, + "records" : [ + ["Bob Dole", 42], + ["Bob Ross", 54], + ["Lewis Carroll", 66] + ] + } + } + } + +レスポンスに含まれる検索結果は、各クエリに付けた一時的な名前で識別することになります。 + +#### 検索のチェーン {#usage-chain} + +検索クエリを列挙する際は、`source` パラメータの値として実在するテーブルの名前だけでなく、別の検索クエリに付けた一時的な名前を指定する事ができます。これにより、1つの検索クエリでは表現できない複雑な検索を行う事ができます。 + +以下は、Personテーブルについて `name` カラムが `Alice` を含んでいるレコードを検索た結果と、それをさらに `sex` カラムの値で集約した結果を同時に取得する例です。 + + { + "type" : "search", + "body" : { + "queries" : { + "people" : { + "source" : "Person", + "condition" : "name @ 'Alice'" + "output" : { + "elements" : ["count", "records"], + "attributes" : ["name", "age"], + "limit" : -1 + } + }, + "sexuality" : { + "source" : "people", + "groupBy" : "sex", + "output" : { + "elements" : ["count", "records"], + "attributes" : ["_key", "_nsubrecs"], + "limit" : -1 + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "people" : { + "count" : 8, + "records" : [ + ["Alice Cooper", 30], + ["Alice Miller", 25], + ["Alice Arnold", 20] + ] + }, + "sexuality" : { + "count" : 2, + "records" : + ["female", 2], + ["male", 1] + ] + } + } + } + +個々の検索クエリの結果は出力しない(中間テーブルとしてのみ使う)事もできます。 +以下は、Personテーブルについて `job` カラムの値で集約した結果をまず求め、そこからさらに `player` という語句を含んでいる項目に絞り込む例です。 +(※この場合の2つ目の検索ではインデックスが使用されないため、検索処理が遅くなる可能性があります。) + + { + "type" : "search", + "body" : { + "queries" : { + "allJob" : { + "source" : "Person", + "groupBy" : "job" + }, + "playerJob" : { + "source" : "allJob", + "condition" : "_key @ `player`", + "output" : { + "elements" : ["count", "records"], + "attributes" : ["_key", "_nsubrecs"], + "limit" : -1 + } + } + } + } + } + + => { + "type" : "search.result", + "body" : { + "playerJob" : { + "count" : 2, + "records" : [ + ["basketball player", 1], + ["baseball player", 1] + ] + } + } + } + + +## パラメータの詳細 {#parameters} + +### 全体のパラメータ {#container-parameters} + +#### `timeout` {#parameter-timeout} + +※註:このパラメータはバージョン {{ site.droonga_version }} では未実装です。指定しても機能しません。 + +概要 +: 検索処理がタイムアウトするまでの時間を指定します。 + +値 +: タイムアウトするまでの時間の数値(単位:ミリ秒)。 + +省略時の初期値 +: 10000(10秒) + +指定した時間以内に Droonga Engine が検索の処理を完了できなかった場合、Droonga はその時点で検索処理を打ち切り、エラーを返却します。 +クライアントは、この時間を過ぎた後は検索処理に関するリソースを解放して問題ありません。 + +#### `queries` {#parameter-queries} + +概要 +: 検索クエリとして、検索の条件と出力の形式を指定します。 + +値 +: 個々の検索クエリの名前をキー、[個々の検索クエリ](#query-parameters)の内容を値としたハッシュ。 + +省略時の既定値 +: なし。このパラメータは必須です。 + +`search` は、複数の検索クエリを一度に受け取る事ができます。 + +バージョン {{ site.droonga_version }} ではすべての検索クエリの結果を一度にレスポンスとして返却する動作のみ対応していますが、将来的には、それぞれの検索クエリの結果を分割して受け取る(結果が出た物からバラバラに受け取る)動作にも対応する予定です。 + +### 個々の検索クエリのパラメータ {#query-parameters} + +#### `source` {#query-source} + +概要 +: 検索対象とするデータソースを指定します。 + +値 +: テーブル名の文字列、または結果を参照する別の検索クエリの名前の文字列。 + +省略時の既定値 +: なし。このパラメータは必須です。 + +別の検索クエリの処理結果をデータソースとして指定する事により、ファセット検索などを行う事ができます。 + +なお、その場合の各検索クエリの実行順(依存関係)は Droonga が自動的に解決します。 +依存関係の順番通りに各検索クエリを並べて記述する必要はありません。 + +#### `condition` {#query-condition} + +概要 +: 検索の条件を指定します。 + +値 +: 以下のパターンのいずれかをとります。 + + 1. [スクリプト構文](http://groonga.org/ja/docs/reference/grn_expr/script_syntax.html)形式の文字列。 + 2. [スクリプト構文](http://groonga.org/ja/docs/reference/grn_expr/script_syntax.html)形式の文字列を含むハッシュ。 + 3. [クエリー構文](http://groonga.org/ja/docs/reference/grn_expr/query_syntax.html)形式の文字列を含むハッシュ。 + 4. 1〜3および演算子の文字列の配列。 + +省略時の既定値 +: なし。 + +検索条件を指定しなかった場合、データソースに含まれるすべてのレコードが検索結果として取り出され、その後の処理に使われます。 + +##### スクリプト構文形式の文字列による検索条件 {#query-condition-script-syntax-string} + +以下のような形式の文字列で検索条件を指定します。 + + "name == 'Alice' && age >= 20" + +上記の例は「 `name` カラムの値が `"Alice"` と等しく、且つ `age` カラムの値が20以上である」という意味になります。 + +詳細は[Groonga のスクリプト構文のリファレンス](http://groonga.org/ja/docs/reference/grn_expr/script_syntax.html)を参照して下さい。 + +##### スクリプト構文形式の文字列を含むハッシュによる検索条件 {#query-condition-script-syntax-hash} + +[スクリプト構文形式の文字列による検索条件](#query-condition-script-syntax-string)をベースとした、以下のような形式のハッシュで検索条件を指定します。 + + { + "script" : "name == 'Alice' && age >= 20", + "allowUpdate" : true + } + +(詳細未稿:仕様が未確定、動作が不明、未実装のため) + +##### クエリー構文形式の文字列を含むハッシュ {#query-condition-query-syntax-hash} + +以下のような形式のハッシュで検索条件を指定します。 + + { + "query" : "Alice", + "matchTo" : ["name * 2", "job * 1"], + "defaultOperator" : "&&", + "allowPragma" : true, + "allowColumn" : true, + "matchEscalationThreshold" : 10 + } + +`query` +: クエリを文字列で指定します。 + 詳細は[Groonga のクエリー構文の仕様](http://groonga.org/ja/docs/reference/grn_expr/query_syntax.html)を参照して下さい。 + このパラメータは省略できません。 + + +: 検索対象のカラムを、カラム名の文字列またはその配列で指定します。 + カラム名の後に `name * 2` のような指定を加える事で、重み付けができます。 + このパラメータは省略可能で、省略時の初期値は `"_key"` です。 + +`defaultOperator`: `query` に複数のクエリが列挙されている場合の既定の論理演算の条件を指定します。 + 以下のいずれかの文字列を指定します。 + + * `"&&"` : AND条件と見なす。 + * `"||"` : OR条件と見なす。 + * `"-"` : [論理否定](http://groonga.org/ja/docs/reference/grn_expr/query_syntax.html#logical-not)条件と見なす。 + + このパラメータは省略可能で、省略時の初期値は `"&&"` です。 + +`allowPragma` +: `query` の先頭において、`*E-1` のようなプラグマの指定を許容するかどうかを真偽値で指定します。 + このパラメータは省略可能で、省略時の初期値は `true` (プラグマの指定を許容する)です。 + +`allowColumn` +: `query` において、カラム名を指定した `name:Alice` のような書き方を許容するかどうかを真偽値で指定します。 + このパラメータは省略可能で、省略時の初期値は `true` (カラム名の指定を許容する)です。 + +`allowLeadingNot` +: `query` において、最初のクエリに `-foobar` のような否定演算子が登場することを許容するかどうかを真偽値で指定します。 + このパラメータは省略可能で、省略時の初期値は `false` (最初のクエリでの否定演算子を許容しない)です。 + +`matchEscalationThreshold` +: 検索方法をエスカレーションするかどうかを決定するための閾値を指定します。 + インデックスを用いた全文検索のヒット件数がこの閾値以下であった場合は、非分かち書き検索、部分一致検索へエスカレーションします。 + 詳細は [Groonga の検索の仕様の説明](http://groonga.org/ja/docs/spec/search.html)を参照して下さい。 + このパラメータは省略可能で、省略時の初期値は `0` です。 + + +##### 配列による検索条件 {#query-condition-array} + +以下のような形式の配列で検索条件を指定します。 + + [ + "&&", + <検索条件1>, + <検索条件2>, + ... + ] + +配列の最初の要素は、論理演算子を以下のいずれかの文字列で指定します。 + + * `"&&"` : AND条件と見なす。 + * `"||"` : OR条件と見なす。 + * `"-"` : [論理否定](http://groonga.org/ja/docs/reference/grn_expr/query_syntax.html#logical-not)条件と見なす。 + +配列の2番目以降の要素で示された検索条件について、1番目の要素で指定した論理演算子による論理演算を行います。 +例えば以下は、スクリプト構文形式の文字列による検索条件2つによるAND条件であると見なされ、「 `name` カラムの値が `"Alice"` と等しく、且つ `age` カラムの値が20以上である」という意味になります。 + + ["&&", "name == 'Alice'", "age >= 20"] + +配列を入れ子にする事により、より複雑な検索条件を指定する事もできます。 +例えば以下は、「 `name` カラムの値が `"Alice"` と等しく、且つ `age` カラムの値が20以上であるが、 `job` カラムの値が `"engineer"` ではない」という意味になります。 + + [ + "-", + ["&&", "name == 'Alice'", "age >= 20"], + "job == 'engineer'" + ] + +#### `sortBy` {#query-sortBy} + +概要 +: ソートの条件および取り出すレコードの範囲を指定します。 + +値 +: 以下のパターンのいずれかをとります。 + + 1. カラム名の文字列の配列。 + 2. ソート条件と取り出すレコードの範囲を指定するハッシュ。 + +省略時の既定値 +: なし。 + +ソート条件が指定されなかった場合、すべての検索結果がそのままの並び順でソート結果として取り出され、その後の処理に使われます。 + +##### 基本的なソート条件の指定 {#query-sortBy-array} + +ソート条件はカラム名の文字列の配列として指定します。 + +Droongaはまず最初に指定したカラムの値でレコードをソートし、カラムの値が同じレコードが複数あった場合は2番目に指定したカラムの値でさらにソートする、という形で、すべての指定カラムの値に基づいてソートを行います。 + +ソート対象のカラムを1つだけ指定する場合であっても、必ず配列として指定する必要があります。 + +ソート順序は指定したカラムの値での昇順となります。カラム名の前に `-` を加えると降順となります。 + +例えば以下は、「 `name` の値で昇順にソートし、同じ値のレコードはさらに `age` の値で降順にソートする」という意味になります。 + + ["name", "-age"] + +##### ソート結果から取り出すレコードの範囲の指定 {#query-sortBy-hash} + +ソートの指定において、以下の形式でソート結果から取り出すレコードの範囲を指定する事ができます。 + + { + "keys" : [<ソート対象のカラム>], + "offset" : <ページングの起点>, + "limit" : <取り出すレコード数> + } + +`keys` +: ソート条件を[基本的なソート条件の指定](#query-sortBy-array)の形式で指定します。 + このパラメータは省略できません。 + +`offset` +: 取り出すレコードのページングの起点を示す `0` または正の整数。 + + このパラメータは省略可能で、省略時の既定値は `0` です。 + +`limit` +: 取り出すレコード数を示す `-1` 、 `0` 、または正の整数。 + `-1`を指定すると、すべてのレコードを取り出します。 + + このパラメータは省略可能で、省略時の既定値は `-1` です。 + +例えば以下は、ソート結果の10番目から19番目までの10件のレコードを取り出すという意味になります。 + + { + "keys" : ["name", "-age"], + "offset" : 10, + "limit" : 10 + } + +これらの指定を行った場合、取り出されたレコードのみがその後の処理の対象となります。 +そのため、 `output` における `offset` および `limit` の指定よりも高速に動作します。 + + +#### `groupBy` {#query-groupBy} + +概要 +: 処理対象のレコード群を集約する条件を指定します。 + +値 +: 以下のパターンのいずれかをとります。 + + 1. 基本的な集約条件(カラム名または式)の文字列。 + 2. 複雑な集約条件を指定するハッシュ。 + +省略時の既定値 +: なし。 + +集約条件を指定した場合、指定に基づいてレコードを集約した結果がレコードとして取り出され、その後の処理に使われます。 + +##### 基本的な集約条件の指定 {#query-groupBy-string} + +基本的な集約条件では、処理対象のレコード群が持つカラムの名前を文字列として指定します。 + +Droongaはそのカラムの値が同じであるレコードを集約し、カラムの値をキーとした新しいレコード群を結果として出力します。 +集約結果のレコードは以下のカラムを持ちます。 + +`_key` +: 集約前のレコード群における、集約対象のカラムの値です。 + +`_nsubrecs` +: 集約前のレコード群における、集約対象のカラムの値が一致するレコードの総数を示す数値です。 + +例えば以下は、`job` カラムの値でレコードを集約し、`job` カラムの値としてどれだけの種類が存在しているのか、および、各 `job` の値を持つレコードが何件存在しているのかを集約結果として取り出すという意味になります。 + + "job" + +##### 複雑な集約条件の指定 {#query-groupBy-hash} + +集約の指定において、集約結果の一部として出力する集約前のレコードの数を、以下の形式で指定する事ができます。 + + { + "key" : "<基本的な集約条件>", + "maxNSubRecords" : <集約結果の一部として出力する集約前のレコードの数> + } + +`key` +: [基本的な集約条件の指定](#query-groupBy-string)の形式による、集約条件を指定する文字列。 + このパラメータは省略できません。 + +`maxNSubRecords` +: 集約結果の一部として出力する集約前のレコードの最大数を示す `0` または正の整数。 + `-1` は指定できません。 + + このパラメータは省略可能で、省略時の既定値は `0` です。 + +例えば以下は、`job` カラムの値でレコードを集約した結果について、各 `job` カラムの値を含んでいるレコードを代表として1件ずつ取り出すという意味になります。 + + { + "key" : "job", + "maxNSubRecords" : 1 + } + +集約結果のレコードは、[基本的な集約条件の指定](#query-groupBy-string)の集約結果のレコード群が持つすべてのカラムに加えて、以下のカラムを持ちます。 + +`_subrecs` +: 集約前のレコード群における、集約対象のカラムの値が一致するレコードの配列。 + +※バージョン {{ site.droonga_version }} では、データセットが複数のボリュームに別れている場合、集約前のレコードの代表が `maxNSubRecords` で指定した数よりも多く返される場合があります。これは既知の問題で、将来のバージョンで修正される予定です。 + + +#### `output` {#query-output} + +概要 +: 処理結果の出力形式を指定します。 + +値 +: 出力形式を指定するハッシュ。 + +省略時の既定値 +: なし。 + +指定を省略した場合、その検索クエリの検索結果はレスポンスには出力されません。 +集約操作などのために必要な中間テーブルにあたる検索結果を求めるだけの検索クエリにおいては、 `output` を省略して処理時間や転送するデータ量を減らすことができます。 + +出力形式は、以下の形式のハッシュで指定します。 + + { + "elements" : [<出力する情報の名前の配列>], + "format" : "<検索結果のレコードの出力スタイル>", + "offset" : <ページングの起点>, + "limit" : <出力するレコード数>, + "attributes" : <レコードのカラムの出力指定の配列> + } + +`elements` +: その検索クエリの結果として[レスポンス](#response)に出力する情報を、プロパティ名の文字列の配列で指定します。 + 以下の項目を指定できます。項目は1つだけ指定する場合であっても必ず配列で指定します。 + + * `"startTime"` + * `"elapsedTime"` + * `"count"` + * `"attributes"` + * `"records"` + + このパラメータは省略可能で、省略時の初期値はありません(結果を何も出力しません)。 + +`format` +: 検索結果のレコードの出力スタイルを指定します。 + 以下のいずれかの値(文字列)を取ります。 + + * `"simple"` : 個々のレコードを配列として出力します。 + * `"complex"` : 個々のレコードをハッシュとして出力します。 + + このパラメータは省略可能で、省略時の初期値は `"simple"` です。 + +`offset` +: 出力するレコードのページングの起点を示す `0` または正の整数。 + + このパラメータは省略可能で、省略時の既定値は `0` です。 + +`limit` +: 出力するレコード数を示す `-1` 、 `0` 、または正の整数。 + `-1`を指定すると、すべてのレコードを出力します。 + + このパラメータは省略可能で、省略時の既定値は `0` です。 + +`attributes` +: レコードのカラムの値について、出力形式を配列で指定します。 + 個々のカラムの値の出力形式は以下のいずれかで指定します。 + + 1. カラムの定義の配列。 + 2. カラムの定義を値としたハッシュ。 + + 各カラムは以下の形式のいずれかで指定します。 + + * カラム名の文字列。例は以下の通りです。 + * `"name"` : `name` カラムの値をそのまま `name` カラムとして出力します。 + * `"age"` : `age` カラムの値をそのまま `age` カラムとして出力します。 + * 詳細な出力形式指定のハッシュ。例は以下の通りです。 + * 以下の例は、 `name` カラムの値を `realName` カラムとして出力します。 + + { "label" : "realName", "source" : "name" } + + * 以下の例は、 `name` カラムの値について、全文検索にヒットした位置を強調したHTMLコード片の文字列を `html` カラムとして出力します。 + + { "label" : "html", "source": "snippet_html(name)" } + + * 以下の例は、`country` カラムについて、すべてのレコードの当該カラムの値が文字列 `"Japan"` であるものとして出力します。 + (存在しないカラムを実際に作成する前にクライアント側の挙動を確認したい場合などに、この機能が利用できます。) + + { "label" : "country", "source" : "'Japan'" } + + * 以下の例は、集約前の元のレコードの総数を、集約後のレコードの `"itemsCount"` カラムの値として出力します。 + + { "label" : "itemsCount", "source" : "_nsubrecs", } + + * 以下の例は、集約前の元のレコードの配列を、集約後のレコードの `"items"` カラムの値として出力します。 + `"attributes"` は、この項の説明と同じ形式で指定します。 + + { "label" : "items", "source" : "_subrecs", + "attributes": ["name", "price"] } + + カラムの定義の配列には、上記の形式で示されたカラムの定義を0個以上含めることができます。例: + + [ + "name", + "age", + { "label" : "realName", "source" : "name" } + ] + + この場合、「`_key` のような特殊なカラムを除くすべてのカラム」を意味する特別なカラム名 `"*"`を使用できます。 + + * `["*"]` と指定すると、(`_key` や `_id` 以外の)すべてのカラムがそのままの形で出力されます。 + * `["_key", "*"]` と指定すると、 `_key` に続いてすべてのカラムがそのままの形で出力されます。 + * `["*", "_nsubrecs"]` と指定すると、 すべてのカラムがそのままの形で出力された後に `_nsubrecs` が出力されます。 + + カラムの定義を値としたハッシュでは、カラムの出力名をキー、上記の形式で示されたカラムの定義を値として、カラムの定義を0個以上含めることができます。例: + + { + "name" : "name", + "age" : "age", + "realName" : { "source" : "name" }, + "country" : { "source" : "'Japan'" } + } + + このパラメータは省略可能で、省略時の既定値はありません。カラムの指定がない場合、カラムの値は一切出力されません。 + + +## レスポンス {#response} + +このコマンドは、検索結果を`body` 、ステータスコード `200` を `statusCode` の値としたレスポンスを返します。 + +検索結果のハッシュは、個々の検索クエリの名前をキー、対応する[個々の検索クエリ](#query-parameters)の処理結果を値とした、以下のような形式を取ります。 + + { + "<クエリ1の名前>" : { + "startTime" : "<検索を開始した時刻>", + "elapsedTime" : <検索にかかった時間(単位:ミリ秒)), + "count" : <指定された検索条件に該当するレコードの総数>, + "attributes" : <出力されたレコードのカラムの情報の配列またはハッシュ>, + "records" : [<出力されたレコードの配列>] + }, + "<クエリ2の名前>" : { ... }, + ... + } + +検索クエリの処理結果のハッシュは以下の項目を持つことができ、[検索クエリの `output`](#query-output) の `elements` で明示的に指定された項目のみが出力されます。 + +### `startTime` {#response-query-startTime} + +検索を開始した時刻(ローカル時刻)の文字列です。 + +形式は、[W3C-DTF](http://www.w3.org/TR/NOTE-datetime "Date and Time Formats")のタイムゾーンを含む形式となります。 +例えば以下の要領です。 + + 2013-11-29T08:15:30+09:00 + +### `elapsedTime` {#response-query-elapsedTime} + +検索にかかった時間の数値(単位:ミリ秒)です。 + +### `count` {#response-query-count} + +検索条件に該当するレコードの総数の数値です。 +この値は、検索クエリの [`sortBy`](#query-sortBy) や [`output`](#query-output) における `offset` および `limit` の指定の影響を受けません。 + +### `attributes` および `records` {#response-query-attributes-and-records} + + * `attributes` は出力されたレコードのカラムの情報を示す配列またはハッシュです。 + * `records` は出力されたレコードの配列です。 + +`attributes` および `records` の出力形式は[検索クエリの `output`](#query-output) の `format` の指定に従って以下の2通りに別れます。 + +#### 単純な形式のレスポンス {#response-query-simple-attributes-and-records} + +`format` が `"simple"` の場合、個々の検索クエリの結果は以下の形を取ります。 + + { + "startTime" : "<検索を開始した時刻>", + "elapsedTime" : <検索にかかった時間), + "count" : <検索結果のレコードの総数>, + "attributes" : [ + { "name" : "<カラム1の名前>", + "type" : "<カラム1の型>", + "vector" : <カラム1がベクターカラムかどうか> }, + { "name" : "<カラム2の名前>", + "type" : "<カラム2の型>", + "vector" : <カラム2がベクターカラムかどうか> }, + { "name" : "<カラム3(サブレコードが存在する場合)の名前>" + "attributes" : [ + { "name" : "<カラム3-1のカラムの名前>", + "type" : "<カラム3-1のカラムの型>", + "vector" : <カラム3-1がベクターカラムかどうか> }, + { "name" : "<カラム3-2のカラムの名前>", + "type" : "<カラム3-2のカラムの型>", + "vector" : <カラム3-2がベクターカラムかどうか> }, + ], + ... + }, + ... + ], + "records" : [ + [<レコード1のカラム1の値>, + <レコード1のカラム2の値>, + [ + [<レコード1のサブレコード1のカラム3-1の値>, + <レコード1のサブレコード1のカラム3-2の値>, + ...], + [<レコード1のサブレコード2のカラム3-1の値>, + <レコード1のサブレコード2のカラム3-2の値>, + ...], + ...], + ...], + [<レコード2のカラム1の値>, + <レコード2のカラム2の値>, + [ + [<レコード2のサブレコード1のカラム3-1の値>, + <レコード2のサブレコード1のカラム3-2の値>, + ...], + [<レコード2のサブレコード2のカラム3-1の値>, + <レコード2のサブレコード2のカラム3-2の値>, + ...], + ...], + ...], + ... + ] + } + +これは、受け取ったデータの扱いやすさよりも、データの転送量を小さく抑える事を優先する出力形式です。 +大量のレコードを検索結果として受け取る場合や、多量のアクセスが想定される場合などに適しています。 + +##### `attributes` {#response-query-simple-attributes} + +出力されたレコードのカラムについての情報の配列で、[検索クエリの `output`](#query-output) における `attributes` で指定された順番で個々のカラムの情報を含みます。 + +個々のカラムの情報はハッシュの形をとり、その形式はレコードの値に応じて以下の3種類で与えられます。ハッシュのキーと値は以下のとおりです。 + +###### 通常のカラム + +`name` +: カラムの出力名の文字列です。[検索クエリの `output`](#query-output) における `attributes` の指定内容に基づきます。 + +`type` +: カラムの値の型を示す文字列です。 + 値は[Groonga のプリミティブなデータ型](http://groonga.org/ja/docs/reference/types.html)の名前か、もしくはテーブル名です。 + +`vector` +: カラムが[ベクター型](http://groonga.org/ja/docs/tutorial/data.html#vector-types)かどうかを示す真偽値です。 + 以下のいずれかの値をとります。 + + * `true` : カラムはベクター型である。 + * `false` : カラムはベクター型ではない(スカラー型である)。 + +###### サブレコードに対応するカラム + +`name` +: カラムの出力名の文字列です。[検索クエリの `output`](#query-output) における `attributes` の指定内容に基づきます。 + +サブレコードのカラム情報を含む配列です。この形式は主レコードの `attributes` と同様です。つまり `attribuets` は再帰的な構造になっています。 + +###### 式 + +`name` +: カラムの出力名の文字列です。[検索クエリの `output`](#query-output) における `attributes` の指定内容に基づきます。 + +##### `records` {#response-query-simple-records} + +出力されたレコードの配列です。 + +個々のレコードは配列の形をとり、[検索クエリの `output`](#query-output) における `attributes` で指定された各カラムの値を同じ順番で含みます。 + +[日時型](http://groonga.org/ja/docs/tutorial/data.html#date-and-time-type)のカラムの値は、[W3C-DTF](http://www.w3.org/TR/NOTE-datetime "Date and Time Formats")のタイムゾーンを含む形式の文字列として出力されます。 + +#### 複雑な形式のレスポンス {#response-query-complex-attributes-and-records} + +`format` が `"complex"` の場合、個々の検索クエリの結果は以下の形を取ります。 + + { + "startTime" : "<検索を開始した時刻>", + "elapsedTime" : <検索にかかった時間), + "count" : <検索結果のレコードの総数>, + "attributes" : { + "<カラム1の名前>" : { "type" : "<カラム1の型>", + "vector" : <カラム1がベクターカラムかどうか> }, + "<カラム2の名前>" : { "type" : "<カラム2の型>", + "vector" : <カラム2がベクターカラムかどうか> }, + "<カラム3(サブレコードが存在する場合)の名前>" : { + "attributes" : { + "<カラム3-1の名前>" : { "type" : "<カラム3-1の型>", + "vector" : <カラム3-1がベクターカラムかどうか> }, + "<カラム3-2の名前>" : { "type" : "<カラム3-2の型>", + "vector" : <カラム3-2がベクターカラムかどうか> }, + ... + } + }, + ... + ], + "records" : [ + { "<カラム1の名前>" : <レコード1のカラム1の値>, + "<カラム2の名前>" : <レコード1のカラム2の値>, + "<カラム3の名前(サブレコードが存在する場合)>" : [ + { "<カラム3-1の名前>" : <レコード1のサブレコード1のカラム3-1の値>, + "<カラム3-2の名前>" : <レコード1のサブレコード1のカラム3-2の値>, + ... }, + { "<カラム3-1の名前>" : <レコード1のサブレコード2のカラム3-1の値>, + "<カラム3-2の名前>" : <レコード1のサブレコード2のカラム3-2の値>, + ... }, + ... + ], + ... }, + { "<カラム1の名前>" : <レコード2のカラム1の値>, + "<カラム2の名前>" : <レコード2のカラム2の値>, + "<カラム3の名前(サブレコードが存在する場合)>" : [ + { "<カラム3-1の名前>" : <レコード2のサブレコード1のカラム3-1の値>, + "<カラム3-2の名前>" : <レコード2のサブレコード1のカラム3-2の値>, + ... }, + { "<カラム3-1の名前>" : <レコード2のサブレコード2のカラム3-1の値>, + "<カラム3-2の名前>" : <レコード2のサブレコード2のカラム3-2の値>, + ... }, + ... + ], + ... }, + ... + ] + } + +これは、データの転送量を小さく抑える事よりも、受け取ったデータの扱いやすさを優先する出力形式です。 +検索結果の件数が小さい事があらかじめ分かっている場合や、管理機能などのそれほど多量のアクセスが見込まれない場合などに適しています。 + +##### `attributes` {#response-query-complex-attributes} + +出力されたレコードのカラムについての情報を含むハッシュで、[検索クエリの `output`](#query-output) における `attributes` で指定された出力カラム名がキー、カラムの情報が値となります。 + +個々のカラムの情報はハッシュの形をとり、その形式はレコードの値に応じて以下の3種類で与えられます。ハッシュのキーと値は以下のとおりです。 + +###### 通常のカラム + +`type` +: カラムの値の型を示す文字列です。 + 値は[Groonga のプリミティブなデータ型](http://groonga.org/ja/docs/reference/types.html)の名前か、もしくはテーブル名です。 + +`vector` +: カラムが[ベクター型](http://groonga.org/ja/docs/tutorial/data.html#vector-types)かどうかを示す真偽値です。 + 以下のいずれかの値をとります。 + + * `true` : カラムはベクター型である。 + * `false` : カラムはベクター型ではない(スカラー型である)。 + +###### サブレコードに対応するカラム + +サブレコードのカラム情報を含む配列です。この形式は主レコードの `attributes` と同様です。つまり `attribuets` は再帰的な構造になっています。 + +###### 式 + +キーはありません。空のハッシュ `{}` です。 + +##### `records` {#response-query-complex-records} + + +出力されたレコードの配列です。 + +個々のレコードは、[検索クエリの `output`](#query-output) における `attributes` で指定された出力カラム名をキー、カラムの値を値としたハッシュとなります。 + +[日時型](http://groonga.org/ja/docs/tutorial/data.html#date-and-time-type)のカラムの値は、[W3C-DTF](http://www.w3.org/TR/NOTE-datetime "Date and Time Formats")のタイムゾーンを含む形式の文字列として出力されます。 + + +## エラーの種類 {#errors} + +このコマンドは[一般的なエラー](/ja/reference/message/#error)に加えて、以下のエラーを場合に応じて返します。 + +### `MissingSourceParameter` + +`source` の指定がないクエリがあることを示します。ステータスコードは `400` です。 + +### `UnknownSource` + +`source` の値として、他のクエリの名前ではない、実際には存在しないテーブルの名前が指定されていることを示します。ステータスコードは `404` です。 + +### `CyclicSource` + +`source` の循環参照があることを示します。ステータスコードは `400` です。 + +### `SearchTimeout` + +`timeout` で指定された時間内に検索処理が完了しなかったことを示します。ステータスコードは `500` です。 Added: ja/reference/1.1.2/commands/select/index.md (+138 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/select/index.md 2015-11-15 23:29:56 +0900 (88ba757) @@ -0,0 +1,138 @@ +--- +title: select +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/select/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`select` は、テーブルから指定された条件にマッチするレコードを検索し、見つかったレコードを返却します。 + +このコマンドは[Groonga の `select` コマンド](http://groonga.org/ja/docs/reference/commands/select.html)と互換性があります。 + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/d/select` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの一覧](#parameters)で定義されている物を指定します。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `select` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `select.result` + +## パラメータの構文 {#syntax} + + { + "table" : "<テーブル名>", + "match_columns" : "<検索対象のカラム名のリストを'||'区切りで指定>", + "query" : "<単純な検索条件>", + "filter" : "<複雑な検索条件>", + "scorer" : "<見つかったすべてのレコードに適用する式>", + "sortby" : "<ソートキーにするカラム名のリストをカンマ(',')区切りで指定>", + "output_columns" : "<L返却するカラム名のリストをカンマ(',')区切りで指定>", + "offset" : <ページングの起点>, + "limit" : <返却するレコード数>, + "drilldown" : "<ドリルダウンするカラム名>", + "drilldown_sortby" : "ドリルダウン結果のソートキーにするカラム名のリストをカンマ(',')区切りで指定>", + "drilldown_output_columns" : + "ドリルダウン結果として返却するカラム名のリストをカンマ(',')区切りで指定>", + "drilldown_offset" : <ドリルダウン結果のページングの起点>, + "drilldown_limit" : <返却するドリルダウン結果のレコード数>, + "cache" : "<クエリキャッシュの指定>", + "match_escalation_threshold": + <検索方法をエスカレーションする閾値>, + "query_flags" : "<queryパラメーターのカスタマイズ用フラグ>", + "query_expander" : "<クエリー展開用の引数>" + } + +## パラメータの詳細 {#parameters} + +`table` 以外のパラメータはすべて省略可能です。 + +また、バージョン {{ site.droonga_version }} の時点では以下のパラメータのみが動作します。これら以外のパラメータは未実装のため無視されます。 + + * `table` + * `match_columns` + * `query` + * `query_flags` + * `filter` + * `output_columns` + * `offset` + * `limit` + * `drilldown` + * `drilldown_output_columns` + * `drilldown_sortby` + * `drilldown_offset` + * `drilldown_limit` + +すべてのパラメータの意味は[Groonga の `select` コマンドの引数](http://groonga.org/ja/docs/reference/commands/select.html#parameters)と共通です。詳細はGroongaのコマンドリファレンスを参照して下さい。 + +## レスポンス {#response} + +このコマンドは、レスポンスの `body` として検索結果の配列を返却します。 + + [ + [ + <Groonga's status code>, + <Start time>, + <Elapsed time> + ], + <List of columns> + ] + +検索結果の配列の構造は[Groonga の `select` コマンドの返り値](http://groonga.org/ja/docs/reference/commands/select.html#id6)と共通です。詳細はGroongaのコマンドリファレンスを参照して下さい。 + +このコマンドはレスポンスの `statusCode` として常に `200` を返します。これは、Groonga互換コマンドのエラー情報はGroongaのそれと同じ形で処理される必要があるためです。 + +レスポンスの `body` の詳細: + +ステータスコード +: コマンドが正常に受け付けられたかどうかを示す整数値です。以下のいずれかの値をとります。 + + * `0` (`Droonga::GroongaHandler::Status::SUCCESS`) : 正常に処理された。. + * `-22` (`Droonga::GroongaHandler::Status::INVALID_ARGUMENT`) : 引数が不正である。 + +開始時刻 +: 処理を開始した時刻を示す数値(UNIX秒)。 + +処理に要した時間 +: 処理を開始してから完了までの間にかかった時間を示す数値。 + Added: ja/reference/1.1.2/commands/system/index.md (+22 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/system/index.md 2015-11-15 23:29:56 +0900 (6d89e1b) @@ -0,0 +1,22 @@ +--- +title: system +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/system/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +`system` は、クラスタのシステム情報を取得するためのコマンド群のための名前空間です。 + + * [system.status](status/): クラスタのステータス情報を取得します。 + * system.statistics + * system.statistics.object + * [system.statistics.object.count](statistics/object/count): データセット内の物理的なオブジェクト数を数えて報告します。 + * [system.statistics.object.count.per-volume](statistics/object/count/per-volume): 各ボリューム内の物理的なオブジェクト数を数えて報告します。 + Added: ja/reference/1.1.2/commands/system/statistics/object/count/index.md (+162 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/system/statistics/object/count/index.md 2015-11-15 23:29:56 +0900 (fcb3847) @@ -0,0 +1,162 @@ +--- +title: system.statistics.object.count +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/system/statistics/object/count/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`system.statistics.object.count` コマンドは、データセット内の物理的なオブジェクト数を数えて報告します。 + +['system.statistics.object.count.per-volume'](per-volume/)も併せて参照して下さい。 + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/droonga/system/statistics/object/count` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの詳細](#parameters)を参照。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `system.statistics.object.count` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `system.statistics.object.count.result` + +## パラメータの構文 {#syntax} + + { + "output": [ + "tables", + "columns", + "records" + ] + } + +または + + { + "output": [ + "total" + ] + } + +## 使い方 {#usage} + +このコマンドは、指定された対象の物理的な数を数えて報告します。 +例: + + { + "type" : "system.statistics.object.count", + "body" : { + "output": [ + "tables", + "columns", + "records", + "total" + ] + } + } + + => { + "type" : "system.statistics.object.count.result", + "body" : { + "tables": 2, + "columns": 0, + "records": 1, + "total": 3 + } + } + + +## パラメータの詳細 {#parameters} + +全てのパラメータは省略可能です。 + +### `output` {#parameter-output} + +概要 +: 個数を報告する対象。 + +値 +: 計数対象の配列。指定された対象のみが計数されます。 + 取り得る値: + + * `tables` + * `columns` + * `records` + * `total` + +省略時の既定値 +: `[]` + + +## レスポンス {#response} + +このコマンドは以下のようなハッシュを `body` 、`200` を `statusCode` としたレスポンスを返します。以下はその一例です。。 + + { + "tables": <テーブルの総数>, + "columns": <カラムの総数>, + "records": <レコードの総数>, + "total": <全てのオブジェクトの総数>, + } + +`tables` +: データセット内の物理的なテーブル数。 + 複数のスライスがある場合、テーブルの個数も多くなります。 + 例えば、2つのテーブルを定義していて2つのスライスがある場合、テーブルの個数は`4`となります。 + +`columns` +: データセット内の物理的なカラム数。 + 複数のスライスがある場合、カラムの個数も多くなります。 + 例えば、2つのテーブルにそれぞれ2つずつのカラムを定義していて、2つのスライスがある場合、カラムの個数は`8`となります。 + +`records` +: データセット内の物理的なレコード数。 + 複数のスライスがある場合、fact表のレコード数の個数も多くなります。 + 例えば、1つのレコードを持つ通常のテーブルと、1つのレコードを持つfact表があり、2つのスライスがある場合、レコードの個数は`3`となります。 + (1つは通常のテーブルのレコード、2つはfact表のレコード) + +`total` +: `tables`、`columns`、`records`の合計。 + 全てのオブジェクトの数の合計だけを知りたい場合は、それぞれの対象を個別に計数するよりも、こちらの方が高速です。 + +## エラーの種類 {#errors} + +このコマンドは[一般的なエラー](/reference/message/#error)を返します。 Added: ja/reference/1.1.2/commands/system/statistics/object/count/per-volume/index.md (+167 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/system/statistics/object/count/per-volume/index.md 2015-11-15 23:29:56 +0900 (df8db03) @@ -0,0 +1,167 @@ +--- +title: system.statistics.object.count.per-volume +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/system/statistics/object/count/per-volume/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`system.statistics.object.count.per-volume` コマンドは、各ボリューム内の物理的なオブジェクト数を数えて報告します。 + +['system.statistics.object.count'](../)も併せて参照して下さい。 + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/droonga/system/statistics/object/count/per-volume` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの詳細](#parameters)を参照。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `system.statistics.object.count.per-volume` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `system.statistics.object.count.per-volume.result` + +## パラメータの構文 {#syntax} + + { + "output": [ + "tables", + "columns", + "records" + ] + } + +または + + { + "output": [ + "total" + ] + } + +## 使い方 {#usage} + +このコマンドは、指定された対象の物理的な数を数えて報告します。 +例: + + { + "type" : "system.statistics.object.count.per-volume", + "body" : { + "output": [ + "tables", + "columns", + "records", + "total" + ] + } + } + + => { + "type" : "system.statistics.object.count.per-volume.result", + "body" : { + "node0:10031/droonga.000": { + "tables": 1, + "columns": 0, + "records": 1, + "total": 2 + }, + "node0:10031/droonga.001": { + "tables": 1, + "columns": 0, + "records": 1, + "total": 2 + } + } + } + + +## パラメータの詳細 {#parameters} + +全てのパラメータは省略可能です。 + +### `output` {#parameter-output} + +概要 +: 個数を報告する対象。 + +値 +: 計数対象の配列。指定された対象のみが計数されます。 + 取り得る値: + + * `tables` + * `columns` + * `records` + * `total` + +省略時の既定値 +: `[]` + + +## レスポンス {#response} + +このコマンドは以下のようなハッシュを `body` 、`200` を `statusCode` としたレスポンスを返します。以下はその一例です。。 + + { + "<1番目のボリュームの識別子>": { + "tables": <テーブルの総数>, + "columns": <カラムの総数>, + "records": <レコードの総数>, + "total": <全てのオブジェクトの総数> + }, + "<2番目のボリュームの識別子>": { ... }, + ... + } + +`tables` +: ボリューム内の物理的なテーブル数。 + +`columns` +: ボリューム内の物理的なカラム数。 + +`records` +: ボリューム内の物理的なレコード数。 + +`total` +: `tables`、`columns`、`records`の合計。 + 全てのオブジェクトの数の合計だけを知りたい場合は、それぞれの対象を個別に計数するよりも、こちらの方が高速です。 + +## エラーの種類 {#errors} + +このコマンドは[一般的なエラー](/reference/message/#error)を返します。 Added: ja/reference/1.1.2/commands/system/status/index.md (+133 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/system/status/index.md 2015-11-15 23:29:56 +0900 (0fbd1be) @@ -0,0 +1,133 @@ +--- +title: system.status +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/system/status/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`system.status` コマンドは、クラスタの現在の状態を返します。 + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/droonga/system/status` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: なし。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `system.status` + +リクエストの `body` +: なし。 + +レスポンスの `type` +: `system.status.result` + +## パラメータの構文 {#syntax} + +このコマンドはパラメータを取りません。 + +## 使い方 {#usage} + +このコマンドは各ノードの死活情報を出力します。 +例: + + { + "type" : "system.status", + "body" : {} + } + + => { + "type" : "system.status.result", + "body" : { + "nodes": { + "192.168.0.10:10031/droonga": { + "status": "active" + }, + "192.168.0.11:10031/droonga": { + "status": "dead" + } + }, + "reporter": "192.168.0.10:49707/droon****@192*****:10031/droonga" + } + } + + +## レスポンス {#response} + +このコマンドは以下のようなハッシュを `body` 、`200` を `statusCode` としたレスポンスを返します。以下はその一例です。。 + + { + "nodes" : { + "<1番目のノードの識別子>" : { + "status" : "<ノードの死活状態>" + }, + "<2番目のノードの識別子>" : { ... }, + ... + }, + "reporter": "<報告者の内部識別名> @ <報告者の識別名>" + } + +`nodes` +: クラスタ内のノードの情報を含むハッシュ。 + ハッシュのキーは、`catalog.json` で定義された各ノードの識別子(形式は `ホスト名:ポート番号/タグ`)です。 + ハッシュの値は対応するノードのステータス情報を表し、以下の情報を含んでいます: + + `status` + : そのノードの死活状態を示す文字列。 + 以下のいずれかの値を取ります: + + * `active`: + ノードは動作していて、サービスを提供している。 + メッセージはそのノード宛に通常通り配送される。 + * `inactive`: + ノードは動作しているが、一時的にサービスから外れている。 + メッセージはそのノード宛にはすぐには配送されない事がある。 + 具体的には、読み込みのみのメッセージ(検索リクエストなど)は全く配送されない。 + データベースへの変更を伴うメッセージ(`add`など)は溜め込まれて、ノードの状態が`active`に復帰した後に配送される。 + * `dead`: + ノードは永続的に停止している。例えば、サービスが停止しているなど。 + + これらのステータスは相対的なもので、ノード同士がお互いの状態を個別に認識して報告します。 + 例えば、異なるロールを持った2つのノードは、お互いに自分を`active`と認識し、相手を`inactive`と認識する場合があります。 + +`reporter` +: どのノードが結果を返したかを示す文字列。 + この情報は、他のノードの状態を間違って認識しているおかしなノードがないかを調べるのに役立ちます。 + +## エラーの種類 {#errors} + +このコマンドは[一般的なエラー](/reference/message/#error)を返します。 Added: ja/reference/1.1.2/commands/table-create/index.md (+111 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/table-create/index.md 2015-11-15 23:29:56 +0900 (c084ad4) @@ -0,0 +1,111 @@ +--- +title: table_create +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/table-create/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`table_create` は、新しいテーブルを作成します。 + +このコマンドは[Groonga の `table_create` コマンド](http://groonga.org/ja/docs/reference/commands/table_create.html)と互換性があります。 + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/d/table_create` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの一覧](#parameters)で定義されている物を指定します。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `table_create` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `table_create.result` + +## パラメータの構文 {#syntax} + + { + "name" : "<テーブル名>", + "flags" : "<テーブルの属性>", + "key_type" : "<主キーの型>", + "value_type" : "<値の型>", + "default_tokenizer" : "<既定のトークナイザー>", + "normalizer" : "<ノーマライザー>" + } + +## パラメータの詳細 {#parameters} + +`name` 以外のパラメータはすべて省略可能です。 + +すべてのパラメータは[Groonga の `table_create` コマンドの引数](http://groonga.org/ja/docs/reference/commands/table_create.html#parameters)と共通です。詳細はGroongaのコマンドリファレンスを参照して下さい。 + +## レスポンス {#response} + +このコマンドは、レスポンスの `body` としてコマンドの実行結果に関する情報を格納した配列を返却します。 + + [ + [ + <Groongaのステータスコード>, + <開始時刻>, + <処理に要した時間> + ], + <テーブルが作成されたかどうか> + ] + +このコマンドはレスポンスの `statusCode` として常に `200` を返します。これは、Groonga互換コマンドのエラー情報はGroongaのそれと同じ形で処理される必要があるためです。 + +レスポンスの `body` の詳細: + +ステータスコード +: コマンドが正常に受け付けられたかどうかを示す整数値です。以下のいずれかの値をとります。 + + * `0` (`Droonga::GroongaHandler::Status::SUCCESS`) : 正常に処理された。. + * `-22` (`Droonga::GroongaHandler::Status::INVALID_ARGUMENT`) : 引数が不正である。 + +開始時刻 +: 処理を開始した時刻を示す数値(UNIX秒)。 + +処理に要した時間 +: 処理を開始してから完了までの間にかかった時間を示す数値。 + +テーブルが作成されたかどうか +: テーブルが作成されたかどうかを示す真偽値です。以下のいずれかの値をとります。 + + * `true`:テーブルを作成した。 + * `false`:テーブルを作成しなかった。 Added: ja/reference/1.1.2/commands/table-list/index.md (+91 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/table-list/index.md 2015-11-15 23:29:56 +0900 (fb66cff) @@ -0,0 +1,91 @@ +--- +title: table_list +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/table-list/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +The `table_list` command reports the list of all existing tables in the dataset. + +This is compatible to [the `table_list` command of the Groonga](http://groonga.org/docs/reference/commands/table_list.html). + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/d/table_list` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: なし。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `table_list` + +リクエストの `body` +: `null` または空のハッシュ。 + +レスポンスの `type` +: `table_list.result` + +## レスポンス {#response} + +This returns an array including list of tables as the response's `body`. + + [ + [ + <Groonga's status code>, + <Start time>, + <Elapsed time> + ], + <List of tables> + ] + +The structure of the returned array is compatible to [the returned value of the Groonga's `table_list` command](http://groonga.org/docs/reference/commands/table_list.html#id5). See the linked document for more details. + +このコマンドはレスポンスの `statusCode` として常に `200` を返します。これは、Groonga互換コマンドのエラー情報はGroongaのそれと同じ形で処理される必要があるためです。 + +レスポンスの `body` の詳細: + +ステータスコード +: コマンドが正常に受け付けられたかどうかを示す整数値です。以下のいずれかの値をとります。 + + * `0` (`Droonga::GroongaHandler::Status::SUCCESS`) : 正常に処理された。. + * `-22` (`Droonga::GroongaHandler::Status::INVALID_ARGUMENT`) : 引数が不正である。 + +開始時刻 +: 処理を開始した時刻を示す数値(UNIX秒)。 + +処理に要した時間 +: 処理を開始してから完了までの間にかかった時間を示す数値。 + Added: ja/reference/1.1.2/commands/table-remove/index.md (+106 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/commands/table-remove/index.md 2015-11-15 23:29:56 +0900 (89b88f5) @@ -0,0 +1,106 @@ +--- +title: table_remove +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/commands/table-remove/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +`table_remove` は、既存のテーブルを1つ削除します。 + +このコマンドは[Groonga の `table_remove` コマンド](http://groonga.org/ja/docs/reference/commands/table_remove.html)と互換性があります。 + +## APIの形式 {#api-types} + +### HTTP {#api-types-http} + +リクエスト先 +: `(ドキュメントルート)/d/table_remove` + +リクエストメソッド +: `GET` + +リクエストのURLパラメータ +: [パラメータの一覧](#parameters)で定義されている物を指定します。 + +リクエストのbody +: なし。 + +レスポンスのbody +: [レスポンスメッセージ](#response)。 + +### REST {#api-types-rest} + +対応していません。 + +### Fluentd {#api-types-fluentd} + +形式 +: Request-Response型。コマンドに対しては必ず対応するレスポンスが返されます。 + +リクエストの `type` +: `table_remove` + +リクエストの `body` +: [パラメータ](#parameters)のハッシュ。 + +レスポンスの `type` +: `table_remove.result` + +## パラメータの構文 {#syntax} + + { + "name" : "<テーブル名>" + } + +## パラメータの詳細 {#parameters} + +唯一のパラメータとなる `name` は省略不可能です。 + +すべてのパラメータは[Groonga の `table_remove` コマンドの引数](http://groonga.org/ja/docs/reference/commands/table_remove.html#parameters)と共通です。詳細はGroongaのコマンドリファレンスを参照して下さい。 + +## レスポンス {#response} + +このコマンドは、レスポンスの `body` としてコマンドの実行結果に関する情報を格納した配列を返却します。 + + [ + [ + <Groongaのステータスコード>, + <開始時刻>, + <処理に要した時間> + ], + <テーブルが削除されたかどうか> + ] + +このコマンドはレスポンスの `statusCode` として常に `200` を返します。これは、Groonga互換コマンドのエラー情報はGroongaのそれと同じ形で処理される必要があるためです。 + +レスポンスの `body` の詳細: + +ステータスコード +: コマンドが正常に受け付けられたかどうかを示す整数値です。以下のいずれかの値をとります。 + + * `0` (`Droonga::GroongaHandler::Status::SUCCESS`) : 正常に処理された。. + * `-22` (`Droonga::GroongaHandler::Status::INVALID_ARGUMENT`) : 引数が不正である。 + +開始時刻 +: 処理を開始した時刻を示す数値(UNIX秒)。 + +処理に要した時間 +: 処理を開始してから完了までの間にかかった時間を示す数値。 + +テーブルが削除されたかどうか +: テーブルが削除されたかどうかを示す真偽値です。以下のいずれかの値をとります。 + + * `true`:テーブルを削除した。 + * `false`:テーブルを削除しなかった。 Added: ja/reference/1.1.2/http-server/index.md (+164 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/http-server/index.md 2015-11-15 23:29:56 +0900 (a4a65dc) @@ -0,0 +1,164 @@ +--- +title: HTTPサーバ +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/http-server/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## 概要 {#abstract} + +[Droonga HTTP Server][droonga-http-server]は、Droonga Engine用のHTTP Protocol Adapterです。 + +Droonga Engineはfluentdプロトコルにのみ対応しているため、Droonga Engineとの通信には`fluent-cat`などを使う必要があります。 +このアプリケーションは、Droonga EngineとHTTP経由で通信するための機能を提供します。 + +## インストール {#install} + +Droonga HTTP Serverは、[Node.js][] 用の[droonga-http-server npmモジュール][droonga-http-server npm module]として提供されています。 +以下のように、`npm`コマンドでインストールすることができます: + + # npm install -g droonga-http-server + +## 使い方 {#usage} + +### コマンドラインオプション {#usage-command} + +Droonga HTTP Serverは、HTTPサーバを起動するための`droonga-http-server`コマンドを含んでいます。 +以下のようにコマンドラインオプションを指定して起動できます: + + # droonga-http-server --port 3003 + +指定可能なオプションと既定値は以下の通りです: + +`--port <13000>` +: HTTPリクエストを受け付けるポート番号。 + +`--receive-host-name <127.0.0.1>` +: HTTPサーバが動作するコンピュータ自身のホスト名(またはIPアドレス)。 + Droonga EngineからProtocol Adapterへレスポンスのメッセージを送出する際の宛先に使われます。 + +`--droonga-engine-host-name <127.0.0.1>` +: Droonga Engineが動作するコンピュータのホスト名(またはIPアドレス)。 + +`--droonga-engine-port <24224>` +: Droonga Engineがメッセージを受け付けるポートの番号。 + +`--default-dataset <Droonga>` +: 既定のデータセット名。 + 組み込みのHTTP APIから発行されるリクエストに使われます。 + +`--tag <droonga>` +: Droonga Engineに送るfluentdメッセージに使われます。 + +`--enable-logging` +: このオプションを指定した場合、ログが標準出力に出力されるようになります。 + +`--cache-size <100>` +: LRUレスポンスキャッシュの最大サイズ。 + Droonga HTTP ServerはすべてのGETリクエストについて、レスポンスをここで指定した件数までメモリ上にキャッシュします。 + +コマンドラインオプションには、組み合わせるDroonga Engineに合わせた値を適切に指定する必要があります。例えば、HTTPサーバが192.168.10.90のコンピュータ上で動作し、Droonga Engineが192.168.10.100のコンピュータ上で以下の設定を伴って動作する時: + +fluentd.conf: + + <source> + type forward + port 24324 + </source> + <match books.message> + name localhost:24224/books + type droonga + </match> + <match output.message> + type stdout + </match> + +catalog.json: + + { + "version": 2, + "effectiveDate": "2013-09-01T00:00:00Z", + "datasets": { + "Books": { + ... + } + } + } + +この時、192.168.10.90のコンピュータ上でHTTPサーバを起動する際のコマンドラインオプションは以下のようになります: + + # droonga-http-server --receive-host-name 192.168.10.90 \ + --droonga-engine-host-name 192.168.10.100 \ + --droonga-engine-port 24324 \ + --default-dataset Books \ + --tag books + +[基本のチュートリアル][basic tutorial]も併せて参照して下さい。 + +## 組み込みのAPI {#usage-api} + +Droonga HTTP Serverは以下のAPIを含んでいます: + +### REST API {#usage-rest} + +#### `GET /tables/<テーブル名>` {#usage-rest-get-tables-table} + +単純な[検索リクエスト](../commands/search/)を発行します。 +リクエストの[`source`](../commands/search/#query-source)は、パス中で指定されたテーブル名となります。 +指定できるクエリパラメータは以下の通りです: + +`attributes` +: [`output.attributes`](../commands/search/#query-output)に対応。 + 値はカンマ区切りのリストです。例:`attributes=_key,name,age`. + +`query` +: [`condition.*.query`](../commands/search/#query-condition-query-syntax-hash)に対応。 + 値はクエリ文字列です。 + +`match_to` +: [`condition.*.matchTo`](../commands/search/#query-condition-query-syntax-hash)に対応。 + 値はカンマ区切りのリストです。例:`match_to=_key,name`. + +`match_escalation_threshold` +: [`condition.*.matchEscalationThreshold`](../commands/search/#query-condition-query-syntax-hash)に対応。 + 値は整数です。 + +`script` +: [`condition`](../commands/search/#query-condition-query-syntax-hash)におけるスクリプト形式の指定に対応。もし`query`と両方同時に指定した場合には、両者の`and`条件と見なされます。 + +`adjusters` +: `adjusters`に対応します。 + +`sort_by` +: [`sortBy`](../commands/search/#query-sortBy)に対応します。 + 値はカラム名の文字列です。 + +`limit` +: [`output.limit`](../commands/search/#query-output)に対応。 + 値は整数です。 + +`offset` +: [`output.offset`](../commands/search/#query-output)に対応。 + 値は整数です。 + +### Groonga HTTPサーバ互換API {#usage-groonga} + +#### `GET /d/<コマンド名>` {#usage-groonga-d} + +(未稿) + + + [basic tutorial]: ../../tutorial/basic/ + [droonga-http-server]: https://github.com/droonga/droonga-http-server + [droonga-http-server npm module]: https://npmjs.org/package/droonga-http-server + [Node.js]: http://nodejs.org/ Added: ja/reference/1.1.2/index.md (+31 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/index.md 2015-11-15 23:29:56 +0900 (ba0f3a3) @@ -0,0 +1,31 @@ +--- +title: リファレンスマニュアル +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +[カタログの仕様](catalog/) +: Droonga Engineの振る舞いを定義する`catalog.json`の詳細。 + +[メッセージの形式](message/) +: Droonga Engine内を流れるメッセージの形式の詳細。 + +[コマンドリファレンス](commands/) +: Droonga Engineで利用可能な組み込みのコマンドの詳細。 + +[コマンドラインツール](command-line-tools/) +: Droongaが提供するコマンドラインツールの使い方の説明。 + +[HTTPサーバ](http-server/) +: [droonga-http-server](https://github.com/droonga/droonga-http-server)の使用方法。 + +[プラグイン開発](plugin/) +: Droonga Engine用の独自のプラグインを開発するための公開APIの詳細。 Added: ja/reference/1.1.2/message/index.md (+247 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/message/index.md 2015-11-15 23:29:56 +0900 (825a020) @@ -0,0 +1,247 @@ +--- +title: メッセージ形式 +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/message/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + + +## リクエスト {#request} + +リクエストのメッセージの基本的な形式は以下の通りです。 + + { + "id" : "<メッセージの識別子>", + "type" : "<メッセージの種類>", + "replyTo" : "<レスポンスの受信者へのパス>", + "dataset" : "<対象データセット名>", + "timeout" : <結果を待つ秒数>, + "targetRole" : "<対象となるロール>", + "body" : <メッセージ本文> + } + +### `id` {#request-id} + +概要 +: そのメッセージの一意な識別子。 + +値 +: 識別子となる文字列。一意でさえあれば、どんな形式のどんな文字列でも指定できます。値は対応するレスポンスの['inReplyTo`](#response-inReplyTo)に使われます。 + +省略時の既定値 +: なし。この情報は省略できません。 + +### `type` {#request-type} + +概要 +: そのメッセージの種類。 + +値 +: [コマンド](/ja/reference/commands/)の名前の文字列 + +省略時の既定値 +: なし。この情報は省略できません。 + +### `replyTo` {#request-replyTo} + +概要 +: レスポンスの受信者へのパス。 + +値 +: `<ホスト>:<ポート番号>/<タグ名>` で示されたパス文字列。例:`localhost:24224/output`. + +省略時の既定値 +: なし。この情報は省略可能で、省略した場合はレスポンスのメッセージは単に捨てられます。 + +### `dataset` {#request-dataset} + +概要 +: 対象となるデータセット。 + +値 +: データセット名の文字列。 + +省略時の既定値 +: なし。この情報は省略できません。 + +### `timeout` {#request-timeout} + +概要 +: リクエストメッセージが有効な期間を示す秒数。 + もし指定された時間までにリクエストに対応する結果が返されなかった場合、システムはそのリクエストに起因するすべてのメッセージの追跡を打ち切ります。 + その際、クライアントはこれを「操作がタイムアウトした」と報告することがあります。 + +値 +: 浮動小数点小数。例:`0.5`. + +省略時の既定値 +: `60`(=1分) + +### `targetRole` {#request-targetRole} + +概要 +: メッセージを処理する対象とするEngineノードのロール。 + メッセージを受け取ったノード自身のロールがこのフィールドの値と異なっていた場合、メッセージはそのロールを持つ他のEngineノードにそのまま転送されます。 + `targetRole`が無い、または特別な値`"any"`が指定された場合、そのノードのロールが何であるかに関わらず、メッセージを受信したノードがメッセージを処理します。 + +値 +: `null`、`"any"`、または以下のいずれか: + + * `"service-provider"` + * `"absorb-source"` + * `"absorb-destination"` + +省略時の初期値 +: `null` + +### `body` {#request-body} + +概要 +: メッセージの本文。 + +値 +: オブジェクト、文字列、数値、真偽値、または `null`。 + +省略時の既定値 +: なし。この情報は省略可能です。 + +## レスポンス {#response} + +レスポンスのメッセージの基本的な形式は以下の通りです。 + + { + "type" : "<メッセージの種類>", + "inReplyTo" : "<対応するリクエストメッセージの識別子>", + "statusCode" : <ステータスコード>, + "body" : <メッセージの本文>, + "errors" : <ノードから返されたエラー> + } + +### `type` {#response-type} + +概要 +: そのメッセージの種類。 + +値 +: メッセージの種類を示す文字列。多くの場合は、元のリクエストメッセージの `type` の値に `.result` という接尾辞を伴った文字列です。 + +### `inReplyTo` {#response-inReplyTo} + +概要 +: 対応するリクエストメッセージの識別子。 + +値 +: 対応するリクエストメッセージの識別子の文字列 related request message. + +### `statusCode` {#response-statusCode} + +概要 +: そのメッセージの種類。 + +値 +: ステータスコードを示す整数。 + +レスポンスのステータスコードはHTTPのステータスコードに似ています。 + +`200` およびその他の `2xx` のステータス +: コマンドが正常に処理されたことを示します。 + +### `body` {#response-body} + +概要 +: そのリクエストメッセージの処理結果の情報。 + +値 +: オブジェクト、文字列、数値、真偽値、または `null`。 + +### `errors` {#response-errors} + +概要 +: 各ノードから返されたすべてのエラー。 + +値 +: オブジェクト。 + +この情報は、コマンドが複数のボリュームに分散して処理された時にのみ現れます。それ以外の場合、レスポンスメッセージは `errors` フィールドを含みません。詳細は[エラーレスポンスの説明](#error)を参照して下さい。 + +## エラーレスポンス {#error} + +コマンドの中にはエラーを返す物があります。 + +エラーレスポンスは通常のレスポンスと同じ `type` を伴って返されますが、通常のレスポンスとは異なる `statusCode` と `body` を持ちます。大まかなエラーの種類は `statusCode` で示され、詳細な情報は `body` の内容として返されます。 + +コマンドが複数のボリュームに分散して処理されて、各ボリュームがエラーを返した場合、レスポンスメッセージは `errors` フィールドを持ちます。各ボリュームから返されたエラーは以下のように保持されます: + + { + "type" : "add.result", + "inReplyTo" : "...", + "statusCode" : 400, + "body" : { + "name": "UnknownTable", + "message": ... + }, + "errors" : { + "/path/to/the/node1" : { + "statusCode" : 400, + "body" : { + "name": "UnknownTable", + "message": ... + } + }, + "/path/to/the/node2" : { + "statusCode" : 400, + "body" : { + "name": "UnknownTable", + "message": ... + } + } + } + } + +このような場合、すべてのエラーの中で代表的な1つがメッセージの `body` に出力されます。 + + +### エラーレスポンスのステータスコード {#error-status} + +エラーレスポンスのステータスコードはHTTPのステータスコードに似ています。 + +`400` およびその他の `4xx` のステータス +: リクエストのメッセージが原因でのエラーであることを示します。 + +`500` およびその他の `5xx` のステータス +: Droonga Engine内部のエラーであることを示します。 + +### エラーレスポンスの `body` {#error-body} + +エラーレスポンスの `body` の基本的な形式は以下の通りです。 + + { + "name" : "<エラーの種類>", + "message" : "<人間が読みやすい形式で示されたエラーの詳細>", + "detail" : <任意の形式の、追加のエラー情報> + } + +追加の情報がない場合、 `detail` は出力されないことがあります。 + +#### エラーの種類 {#error-type} + +すべてのコマンドに共通するエラーとして、以下の物があります。 + +`MissingDatasetParameter` +: `dataset` の指定がないことを示します。ステータスコードは `400` です。 + +`UnknownDataset` +: 指定されたデータセットが存在しないことを示します。ステータスコードは `404` です。 + +`UnknownType` +: `type` に指定されたコマンドを処理するハンドラが存在しない、未知のコマンドであることを示します。ステータスコードは `400` です。 Added: ja/reference/1.1.2/plugin/adapter/index.md (+317 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/plugin/adapter/index.md 2015-11-15 23:29:56 +0900 (0c5661e) @@ -0,0 +1,317 @@ +--- +title: 適合フェーズでのプラグインAPI +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/plugin/adapter/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + + +## 概要 {#abstract} + +各々のDroonga Engineプラグインは、それ自身のための*アダプター*を持つことができます。適合フェーズでは、アダプターは入力メッセージ(Protocol AdapterからDroonga Engineへ送られてきたリクエストに相当)と出力メッセージ(Droonga EngineからProtocol Adapterへ送られるレスポンスに相当)の両方について変更を加えることができます。 + + +### アダプターの定義の仕方 {#howto-define} + +例えば、「foo」という名前のプラグインにアダプターを定義する場合は以下のようにします: + +~~~ruby +require "droonga/plugin" + +module Droonga::Plugins::FooPlugin + extend Plugin + register("foo") + + class Adapter < Droonga::Adapter + # このアダプターを設定するための操作 + XXXXXX = XXXXXX + + def adapt_input(input_message) + # 入力メッセージを変更するための操作 + input_message.XXXXXX = XXXXXX + end + + def adapt_output(output_message) + # 出力メッセージを変更するための操作 + output_message.XXXXXX = XXXXXX + end + end +end +~~~ + +アダプターを定義するための手順は以下の通りです: + + 1. プラグイン用のモジュール(例:`Droonga::Plugins::FooPlugin`)を定義し、プラグインとして登録する。(必須) + 2. [`Droonga::Adapter`](#classes-Droonga-Adapter)を継承したアダプタークラス(例:`Droonga::Plugins::FooPlugin::Adapter`)を定義する。(必須) + 3. [アダプターを適用する条件を設定する](#howto-configure)。(必須) + 4. 入力メッセージに対する変更操作を[`#adapt_input`](#classes-Droonga-Adapter-adapt_input)として定義する。(任意) + 5. 出力メッセージに対する変更操作を[`#adapt_output`](#classes-Droonga-Adapter-adapt_output)として定義する。(任意) + +[プラグイン開発のチュートリアル](../../../tutorial/plugin-development/adapter/)も参照して下さい。 + + +### アダプターはどのように操作するか {#how-works} + +アダプターは以下のように動作します: + + 1. Droonga Engineが起動する。 + * アダプタークラス(例:`Droonga::Plugins::FooPlugin::Adapter`)の唯一のインスタンスが作られ、登録される。 + * 入力のマッチングパターンおよび出力のマッチングパターンが登録される。 + * Droonga Engineが起動し、入力メッセージを待ち受ける。 + 2. 入力メッセージがProtocol AdapterからDroonga Engineへ送られてくる。 + この時点で(入力メッセージ用の)適合フェーズが開始される。 + * そのメッセージが[入力のマッチングパターン](#config)にマッチするアダプターについて、アダプターの[`#adapt_input`](#classes-Droonga-Adapter-adapt_input)が呼ばれる。 + * このメソッドは、[入力メッセージ自身が持つメソッド](#classes-Droonga-InputMessage)を通じて入力メッセージを変更することができる。 + 3. すべてのアダプターが適用された時点で、入力メッセージ用の適合フェーズが終了し、メッセージが次の立案フェーズに送られる。 + 4. 出力メッセージが前の集約フェーズから送られてくる。 + この時点で(出力メッセージ用の)適合フェーズが開始される。 + * そのメッセージ外貨の両方の条件を満たす場合に、アダプターの[`#adapt_output`](#classes-Droonga-Adapter-adapt_output)が呼ばれる: + - そのメッセージが、そのアダプター自身によって処理された入力メッセージに起因した物である。 + - そのメッセージが、アダプターの[出力のマッチングパターン](#config)にマッチする。 + * このメソッドは、[出力メッセージ自身が持つメソッド](#classes-Droonga-OutputMessage)を通じて出力メッセージを変更することができる。 + 5. すべてのアダプターが適用された時点で、出力メッセージ用の適合フェーズが終了し、メッセージがProtocol Adapterに送られる。 + +上記の通り、Droonga Engineは各プラグインのアダプタークラスについて、インスタンスを全体で1つだけ生成します。 +対になった入力メッセージと出力メッセージのための状態を示す情報をアダプター自身のインスタンス変数として保持してはいけません。 +代わりに、状態を示す情報を入力メッセージのbodyの一部として埋め込み、対応する出力メッセージのbodyから取り出すようにして下さい。 + +アダプター内で発生したすべてのエラーは、Droonga Engine自身によって処理されます。[エラー処理][error handling]も併せて参照して下さい。 + + +## 設定 {#config} + +`input_message.pattern` ([マッチングパターン][matching pattern], 省略可能, 初期値=`nil`) +: 入力メッセージに対する[マッチングパターン][matching pattern]。 + パターンが指定されていない(もしくは`nil`が指定された)場合は、すべてのメッセージがマッチします。 + +`output_message.pattern` ([マッチングパターン][matching pattern], 省略可能, 初期値=`nil`) +: 出力メッセージに対する[マッチングパターン][matching pattern]。 + パターンが指定されていない(もしくは`nil`が指定された)場合は、すべてのメッセージがマッチします。 + +## クラスとメソッド {#classes} + +### `Droonga::Adapter` {#classes-Droonga-Adapter} + +これはすべてのアダプターに共通の基底クラスです。独自プラグインのアダプタークラスは、このクラスを継承する必要があります。 + +#### `#adapt_input(input_message)` {#classes-Droonga-Adapter-adapt_input} + +このメソッドは、[`Droonga::InputMessage`](#classes-Droonga-InputMessage)でラップされた入力メッセージを受け取ります。 +入力メッセージは、メソッドを通じて内容を変更することができます。 + +この基底クラスにおいて、このメソッドは何もしない単なるプレースホルダとして定義されています。 +入力メッセージを変更するには、以下のようにメソッドを再定義して下さい: + +~~~ruby +module Droonga::Plugins::QueryFixer + class Adapter < Droonga::Adapter + def adapt_input(input_message) + input_message.body["query"] = "fixed query" + end + end +end +~~~ + +#### `#adapt_output(output_message)` {#classes-Droonga-Adapter-adapt_output} + +このメソッドは、[`Droonga::OutputMessage`](#classes-Droonga-OutputMessage)でラップされた出力メッセージを受け取ります。 +出力メッセージは、メソッドを通じて内容を変更することができます。 + +この基底クラスにおいて、このメソッドは何もしない単なるプレースホルダとして定義されています。 +出力メッセージを変更するには、以下のようにメソッドを再定義して下さい: + +~~~ruby +module Droonga::Plugins::ErrorConcealer + class Adapter < Droonga::Adapter + def adapt_output(output_message) + output_message.status_code = Droonga::StatusCode::OK + end + end +end +~~~ + +### `Droonga::InputMessage` {#classes-Droonga-InputMessage} + +#### `#type`, `#type=(type)` {#classes-Droonga-InputMessage-type} + +入力メッセージの`"type"`の値を返します。 + +以下のように、新しい文字列値を代入することで値を変更できます: + +~~~ruby +module Droonga::Plugins::MySearch + class Adapter < Droonga::Adapter + input_message.pattern = ["type", :equal, "my-search"] + + def adapt_input(input_message) + p input_message.type + # => "my-search" + # このメッセージは「my-search」というメッセージタイプに + # 対応したプラグインによって処理される。 + + input_message.type = "search" + + p input_message.type + # => "search" + # メッセージタイプが変更された。 + # このメッセージはsearchプラグインによって、 + # 通常の検索リクエストとして処理される。 + end + end +end +~~~ + +#### `#body`, `#body=(body)` {#classes-Droonga-InputMessage-body} + +入力メッセージの`"body"`の値を返します。 + +以下のように、新しい値を代入したり部分的に値を代入したりすることで、値を変更することができます: + +~~~ruby +module Droonga::Plugins::MinimumLimit + class Adapter < Droonga::Adapter + input_message.pattern = ["type", :equal, "search"] + + MAXIMUM_LIMIT = 10 + + def adapt_input(input_message) + input_message.body["queries"].each do |name, query| + query["output"] ||= {} + query["output"]["limit"] ||= MAXIMUM_LIMIT + query["output"]["limit"] = [query["output"]["limit"], MAXIMUM_LIMIT].min + end + # この時点で、すべての検索クエリが"output.limit=10"の指定を持っている。 + end + end +end +~~~ + +別の例: + +~~~ruby +module Droonga::Plugins::MySearch + class Adapter < Droonga::Adapter + input_message.pattern = ["type", :equal, "my-search"] + + def adapt_input(input_message) + # 独自形式のメッセージからクエリ文字列を取り出す。 + query_string = input_message["body"]["query"] + + # "search"型の内部的な検索リクエストを組み立てる。 + input_message.type = "search" + input_message.body = { + "queries" => { + "source" => "Store", + "condition" => { + "query" => query_string, + "matchTo" => ["name"], + }, + "output" => { + "elements" => ["records"], + "limit" => 10, + }, + }, + } + # この時点で、"type"と"body"は両方とも完全に置き換えられている。 + end + end +end +~~~ + +### `Droonga::OutputMessage` {#classes-Droonga-OutputMessage} + +#### `#status_code`, `#status_code=(status_code)` {#classes-Droonga-OutputMessage-status_code} + +出力メッセージの`"statusCode"`の値を返します。 + +以下のように、新しいステータスコードを代入することで値を変更できます: + +~~~ruby +module Droonga::Plugins::ErrorConcealer + class Adapter < Droonga::Adapter + input_message.pattern = ["type", :equal, "search"] + + def adapt_output(output_message) + unless output_message.status_code == StatusCode::InternalServerError + output_message.status_code = Droonga::StatusCode::OK + output_message.body = {} + output_message.errors = nil + # この時点で、内部的なサーバーエラーはすべて無視されるため + # クライアントは通常のレスポンスを受け取る事になる。 + end + end + end +end +~~~ + +#### `#errors`, `#errors=(errors)` {#classes-Droonga-OutputMessage-errors} + +出力メッセージの`"errors"`の値を返します。 + +以下のように、新しいエラー情報を代入したり値を部分的に書き換えたりする事ができます: + +~~~ruby +module Droonga::Plugins::ErrorExporter + class Adapter < Droonga::Adapter + input_message.pattern = ["type", :equal, "search"] + + def adapt_output(output_message) + output_message.errors.delete(secret_database) + # 秘密のデータベースからのエラー情報を削除する。 + + output_message.body["errors"] = { + "records" => output_message.errors.collect do |database, error| + { + "database" => database, + "error" => error + } + end, + } + # エラー情報を、"error"という名前の擬似的な検索結果に変換する。 + end + end +end +~~~ + +#### `#body`, `#body=(body)` {#classes-Droonga-OutputMessage-body} + +出力メッセージの`"body"`の値を返します。 + +以下のように、新しい値を代入したり部分的に値を代入したりすることで、値を変更することができます: + +~~~ruby +module Droonga::Plugins::SponsoredSearch + class Adapter < Droonga::Adapter + input_message.pattern = ["type", :equal, "search"] + + def adapt_output(output_message) + output_message.body.each do |name, result| + next unless result["records"] + result["records"].unshift(sponsored_entry) + end + # これにより、すべての検索結果が広告エントリを含むようになる。 + end + + def sponsored_entry + { + "title"=> "SALE!", + "url"=> "http://..." + } + end + end +end +~~~ + + + [matching pattern]: ../matching-pattern/ + [error handling]: ../error/ Added: ja/reference/1.1.2/plugin/collector/index.md (+58 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/plugin/collector/index.md 2015-11-15 23:29:56 +0900 (f9648c7) @@ -0,0 +1,58 @@ +--- +title: コレクター +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/plugin/collector/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + + +## 概要 {#abstract} + +コレクターは、2つの入力値を1つの値に結合します。 +Droonga Engineは3つ以上の値に対しても、指定されたコレクターを繰り返し適用することによって、それらを1つの値にします。 + +## 組み込みのコレクタークラス {#builtin-collectors} + +組み込みのプラグインによって使われている、定義済みのコレクタークラスがいくつかあります。 +これらは当然ですが、自作プラグインからも利用することができます。 + +### `Droonga::Collectors::And` + +`and` 論理演算子によって2つの値を比較した結果を返します。 +両方の値が論理的に真である場合、どちらかの値が返されます(どちらが返されるかは不定です)。 + +`null` (`nil`) および `false` は論理的に偽として扱われ、それ以外の場合はすべて真として扱われます。 + +### `Droonga::Collectors::Or` + +`or` 論理演算子によって2つの値を比較した結果を返します。 +片方の値だけが論理的に真である場合、その値が返り値となります。 +そうでなく2つの値が論理的に等しい場合は、どちらかの値が返されます(どちらが返されるかは不定です)。 + +`null` (`nil`) および `false` は論理的に偽として扱われ、それ以外の場合はすべて真として扱われます。 + +### `Droonga::Collectors::Sum` + +2つの値のまとめた結果を返します。 + +このコレクターは若干複雑な動作をします。 + + * 片方の値が `null` (`nil`) である場合、もう片方の値を返します。 + * 両方の値がハッシュである場合、ハッシュの結合結果を値として返します。 + * 結果のハッシュは、2つのハッシュが持つキーのすべてを持ちます。 + 両方のハッシュでキーが重複した場合、重複したキーの値はどちらかのハッシュの値となります。 + * 重複するキーの値についてどちらのハッシュの値が使われるかは不定です。 + * それ以外の場合は、 `a + b` の結果を値として返します。 + * 両方ともの値が配列または文字列であった場合、それらを連結した結果を値として返します。 + どちらの値が左辺になるかは不定です。 + Added: ja/reference/1.1.2/plugin/error/index.md (+70 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/plugin/error/index.md 2015-11-15 23:29:56 +0900 (6968852) @@ -0,0 +1,70 @@ +--- +title: プラグインでのエラーの扱い +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/plugin/error/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + + +## 概要 {#abstract} + +プラグイン内部で発生した例外のうち、そのプラグイン自身によって補足されなかった物は、すべて、入力メッセージに対する[エラーレスポンス][error response]として返されます。この時のエラーレスポンスのステータスコードは`500`(Internal Errorを意味する)です。 + +整形されたエラー情報を返したい場合は、低レベルのエラーを捕捉した上で、`Droonga::ErrorMessage::BadRequest`または`Droonga::ErrorMessage::InternalServerError`を継承したカスタムエラークラスでラップして再度`raise`して下さい。 +(ちなみに、これらの基底クラスはプラグインの名前空間に初期状態で`include`されているため、エラークラスの定義時には単に`class CustomError < BadRequest`などと書くだけで参照できます。) + + +## 組み込みのエラークラス {#builtin-errors} + +組み込みのプラグインやDroonga Engine自身によってあらかじめ定義されているエラークラスとしては、以下の物があります。 + +### `Droonga::ErrorMessage::NotFound` + +データセットまたは指定された情報ソースの中に、探している情報が見つからなかったことを示す。例: + + # 第2引数はエラーの詳細な情報。(省略可能) + raise Droonga::NotFound.new("#{name} is not found!", :elapsed_time => elapsed_time) + +### `Droonga::ErrorMessage::BadRequest` + +文法エラーやバリデーションエラーなど、入力メッセージ自体にエラーが含まれていたことを示す。例: + + # 第2引数はエラーの詳細な情報。(省略可能) + raise Droonga::NotFound.new("Syntax error in #{query}!", :detail => detail) + +### `Droonga::ErrorMessage::InternalServerError` + +タイムアウト、ファイル入出力のエラーなど、その他の未知のエラーであることを示す。例: + + # 第2引数はエラーの詳細な情報。(省略可能) + raise Droonga::MessageProcessingError.new("busy!", :elapsed_time => elapsed_time) + + +## 組み込みのステータスコード {#builtin-status-codes} + +エラーのステータスコードとしては、以下のステータスコードか、もしくは[慣習に従ったステータスコード](../../message/#error-status)を使用します。 + +`Droonga::StatusCode::OK` +: `200`と等価。 + +`Droonga::StatusCode::NOT_FOUND` +: `404`と等価。 + +`Droonga::StatusCode::BAD_REQUEST` +: `400`と等価。 + +`Droonga::StatusCode::INTERNAL_ERROR` +: `500`と等価。 + + + [error response]: ../../message/#error Added: ja/reference/1.1.2/plugin/handler/index.md (+230 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/plugin/handler/index.md 2015-11-15 23:29:56 +0900 (83f681b) @@ -0,0 +1,230 @@ +--- +title: ハンドリング・フェーズでのプラグインAPI +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/plugin/handler/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + + +## 概要 {#abstract} + +各々のDroonga Engineプラグインは、それ自身のための*ハンドラー*を持つことができます。ハンドリング・フェーズでは、ハンドラーはリクエストを処理して結果を返すことができます。 + + +### ハンドラーの定義の仕方 {#howto-define} + +例えば、「foo」という名前のプラグインにハンドラーを定義する場合は以下のようにします: + +~~~ruby +require "droonga/plugin" + +module Droonga::Plugins::FooPlugin + extend Plugin + register("foo") + + define_single_step do |step| + step.name = "foo" + step.handler = :Handler + step.collector = Collectors::And + end + + class Handler < Droonga::Handler + def handle(message) + # リクエストを処理するための操作 + end + end +end +~~~ + +ハンドラーを定義するための手順は以下の通りです: + + 1. プラグイン用のモジュール(例:`Droonga::Plugins::FooPlugin`)を定義し、プラグインとして登録する。(必須) + 2. [`Droonga::SingleStepDefinition`](#class-Droonga-SingleStepDefinition)を使い、実装しようとしているハンドラーに対応する「single step」を定義する。(必須) + 3. [`Droonga::Handler`](#classes-Droonga-Handler)を継承したハンドラークラス(例:`Droonga::Plugins::FooPlugin::Handler`)を定義する。(必須) + 4. リクエストを処理する操作を[`#handle`](#classes-Droonga-Handler-handle)として定義する。(任意) + + +[プラグイン開発チュートリアル](../../../tutorial/plugin-development/handler/)も併せて参照して下さい。 + + +### ハンドラーはどのように操作するか {#how-works} + +ハンドラーは以下のように動作します: + + 1. Droonga Engineが起動する。 + * stepとハンドラークラスが登録される。 + * Droonga Engineが起動し、入力メッセージを待ち受ける。 + 2. 適合フェーズからメッセージが転送されてくる。 + この時点で処理フェーズが開始される。 + * Droonga Engineが、メッセージタイプからstepの定義を見つける。 + * Droonga Engineが、登録済みの定義に従ってsingle stepを作成する。 + * single stepが、登録済みのハンドラークラスのインスタンスを作成する。 + この時点でハンドリング・フェーズが開始される。 + * ハンドラーの[`#handle`](#classes-Droonga-Handler-handle)メソッドが、リクエストの情報を含むタスクメッセージを伴って呼ばれる。 + * このメソッドにより、入力メッセージを任意に処理することができる。 + * このメソッドは、処理結果の出力を戻り値として返す。 + * ハンドラーの処理が完了した時点で、そのタスクメッセージ(およびリクエスト)のハンドリング・フェーズが終了する。 + * メッセージタイプからstepが見つからなかった場合は、何も処理されない。 + * すべてのstepが処理を終えた時点で、そのリクエストに対する処理フェーズが終了する。 + +上記の通り、Droonga Engineは各リクエストに対してその都度ハンドラークラスのインスタンスを生成します。 + +ハンドラー内で発生したすべてのエラーは、Droonga Engine自身によって処理されます。[エラー処理][error handling]も併せて参照して下さい。 + + +## 設定 {#config} + +`action.synchronous` (真偽値, 省略可能, 初期値=`false`) +: リクエストを同期的に処理する必要があるかどうかを示す。 + 例えば、テーブル内に新しいカラムを追加するリクエストは、テーブルが存在しない場合には必ず、テーブル作成用のリクエストの後で処理する必要がある。このような場合のハンドラーは、 `action.synchronous = true` の指定を伴うことになる。 + + +## クラスとメソッド {#classes} + +### `Droonga::SingleStepDefinition` {#classes-Droonga-SingleStepDefinition} + +このクラスは、ハンドラーに対応するstepの詳細を記述する機能を提供します。 + +#### `#name`, `#name=(name)` {#classes-Droonga-SingleStepDefinition-name} + +step自身の名前を記述します。値は文字列です。 + +Droonga Engineは、メッセージの`type`に一致する`name`を持つstepが存在する場合に、入力メッセージをコマンドのリクエストとして扱います。 +言い換えると、このメソッドはstepに対応するコマンドの名前を定義します。 + + +#### `#handler`, `#handler=(handler)` {#classes-Droonga-SingleStepDefinition-handler} + +特定のハンドラークラスをstepに紐付けます。 +ハンドラークラスは以下のいずれかの方法で指定します: + + * `Handler` や `Droonga::Plugins::FooPlugin::Handler` のような、ハンドラークラス自体への参照。 + 当然ながら、参照先のクラスはその時点で定義済みでなければなりません。 + * `:Handler`のような、その名前空間で定義されているハンドラークラスのクラス名のシンボル。 + この記法は、stepを先に記述して後からハンドラークラスを定義する場合に有用です。 + * `"Droonga::Plugins::FooPlugin::Handler"` のような、ハンドラークラスのクラスパス文字列。 + この記法もまた、stepの後でハンドラークラスを定義する場合に有用です。 + +ハンドラークラスをシンボルまたは文字列で指定した場合、参照先のクラスは、Droonga Engineが実際にそのstepを処理する時点までの間に定義しておく必要があります。 +Droonga Engineがハンドラークラスの実体を見つけられなかった場合、またはハンドラークラスが未指定の場合には、Droonga Engineはそのリクエストに対して何も処理を行いません。 + +#### `#collector`, `#collector=(collector)` {#classes-Droonga-SingleStepDefinition-collector} + +特定のコレクタークラスをstepに紐付けます。 +コレクタークラスは以下のいずれかの方法で指定します: + + * `Collectors::Something` や `Droonga::Plugins::FooPlugin::MyCollector` のような、コレクタークラス自体への参照。 + 当然ながら、参照先のクラスはその時点で定義済みでなければなりません。 + * `:MyCollector`のような、その名前空間で定義されているコレクタークラスのクラス名のシンボル。 + この記法は、stepを先に記述して後からコレクタークラスを定義する場合に有用です。 + * `"Droonga::Plugins::FooPlugin::MyCollector"` のような、コレクタークラスのクラスパス文字列。 + この記法もまた、stepの後でコレクタークラスを定義する場合に有用です。 + +コレクタークラスをシンボルまたは文字列で指定した場合、参照先のクラスは、Droonga Engineが実際にそのstepの結果を集約する時点までの間に定義しておく必要があります。 +Droonga Engineがコレクタークラスの実体を見つけられなかった場合、またはコレクタークラスが未指定の場合には、Droonga Engineは処理結果を集約せず、複数のメッセージとして返します。 + +[コレクターの説明][collector]も併せて参照して下さい。 + +#### `#write`, `#write=(write)` {#classes-Droonga-SingleStepDefinition-write} + +stepがストレージ内の情報を変更し得るかどうかを記述します。 +リクエストがストレージ内のデータを変更することを意図する物である場合、そのリクエストはすべてのreplicaで処理される必要があります。 +それ以外の場合、Droonga Engineは結果をキャッシュしたり、CPUやメモリの使用量を削減するなどして、処理を最適化することができます。 + +取り得る値: + + * `true`: そのstepではストレージの内容が変更される可能性がある事を示す。 + * `false`: そのstepではストレージの内容が変更される可能性はない事を示す。(初期値)" + +#### `#inputs`, `#inputs=(inputs)` {#classes-Droonga-SingleStepDefinition-inputs} + +(未稿) + +#### `#output`, `#output=(output)` {#classes-Droonga-SingleStepDefinition-output} + +(未稿) + +### `Droonga::Handler` {#classes-Droonga-Handler} + +これはすべてのハンドラーに共通の基底クラスです。独自プラグインのハンドラークラスは、このクラスを継承する必要があります。 + +#### `#handle(message)` {#classes-Droonga-Handler-handle} + +このメソッドは、[`Droonga::HandlerMessage`](#classes-Droonga-HandlerMessage)でラップされたタスクメッセージを受け取ります。 +プラグインは、このタスクメッセージのメソッドからリクエストの情報を読み取る事ができます。 + +この基底クラスにおいて、このメソッドは何もしない単なるプレースホルダとして定義されています。 +メッセージを処理するには、以下のようにメソッドを再定義して下さい: + +~~~ruby +module Droonga::Plugins::MySearch + class Handler < Droonga::Handler + def handle(message) + search_query = message.request["body"]["query"] + ... + { ... } # the result + end + end +end +~~~ + +Droonga Engineは、このメソッドの戻り値を処理の結果として扱います。 +結果の値は、レスポンスのbodyの組み立てに使われ、Protocol Adapterに送られます。 + + +### `Droonga::HandlerMessage` {#classes-Droonga-HandlerMessage} + +このクラスはタスクメッセージに対するラッパーとして働きます。 + +Droonga Engineは送られてきたリクエストのメッセージを解析し、そのリクエストを処理するための複数のタスクメッセージを作成します。 +1つのタスクメッセージは、リクエストの実体、step、後続するタスクの一覧などの情報を持ちます。 + +#### `#request` {#classes-Droonga-HandlerMessage-request} + +このメソッドはリクエストメッセージを返します。例: + +~~~ruby +module Droonga::Plugins::MySearch + class Handler < Droonga::Handler + def handle(message) + request = message.request + search_query = request["body"]["query"] + ... + end + end +end +~~~ + +#### `@context` {#classes-Droonga-HandlerMessage-context} + +対応するボリュームのストレージを示す、`Groonga::Context`のインスタンスへの参照。 +[Rroongaのクラスリファレンス][Groonga::Context]も併せて参照して下さい + +`@context`を経由して、Rroongaのすべての機能を利用できます。 +例えば、以下は指定されたテーブルのすべてのレコードの数を返す例です: + +~~~ruby +module Droonga::Plugins::CountRecords + class Handler < Droonga::Handler + def handle(message) + request = message.request + table_name = request["body"]["table"] + count = @context[table_name].size + end + end +end +~~~ + + [error handling]: ../error/ + [collector]: ../collector/ + [Groonga::Context]: http://ranguba.org/rroonga/en/Groonga/Context.html Added: ja/reference/1.1.2/plugin/index.md (+21 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/plugin/index.md 2015-11-15 23:29:56 +0900 (9ae44ad) @@ -0,0 +1,21 @@ +--- +title: プラグイン開発 +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/plugin/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +Droonga Engineはプラグインに対して、処理の各段階ごとに異なるAPIセットを提供します。[プラグイン開発のチュートリアル](../../tutorial/plugin-development/)も参照してください。 + + * [適合フェーズでのAPI](adapter/) + * [ハンドリング・フェーズでのAPI](handler/) + * [メッセージのためのマッチングパターン](matching-pattern/) + * [コレクター](collector/) + * [エラー処理](error/) Added: ja/reference/1.1.2/plugin/matching-pattern/index.md (+242 -0) 100644 =================================================================== --- /dev/null +++ ja/reference/1.1.2/plugin/matching-pattern/index.md 2015-11-15 23:29:56 +0900 (e7ee19d) @@ -0,0 +1,242 @@ +--- +title: メッセージのマッチングパターン +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/reference/1.1.2/plugin/matching-pattern/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + + +## 概要 {#abstract} + +Droonga Engineはメッセージのパターンを指定するための小規模な言語を実装しています。これを*マッチングパターン*と呼びます。 +マッチングパターンは、プラグインなどの様々な場所で処理対象のメッセージを指定するために使われます。 + + +## 例 {#examples} + +### 単純なマッチング + + pattern = ["type", :equal, "search"] + +これは以下のようなメッセージにマッチします: + + { + "type": "search", + ... + } + +### 深い位置にある対象へのマッチング + + pattern = ["body.success", :equal, true] + +これは以下のようなメッセージにマッチします: + + { + "type": "add.result", + "body": { + "success": true + } + } + +以下にはマッチしません: + + { + "type": "add.result", + "body": { + "success": false + } + } + +### パターン自体のネスト + + pattern = [ + ["type", :equal, "table_create"], + :or, + ["body.success", :equal, true] + ] + +これは以下の両方にマッチします: + + { + "type": "table_create", + ... + } + +および: + + { + "type": "column_create", + ... + "body": { + "success": true + } + } + + +## 書式 {#syntax} + +マッチングパターンには「基本パターン」と「ネストしたパターン」の2種類があります。 + +### 基本パターン {#syntax-basic} + +#### 構造 {#syntax-basic-structure} + +基本パターンは以下のように、2つ以上の要素を含む配列として表現されます: + + ["type", :equal, "search"] + + * 最初の要素は *ターゲットパス* です。これは、[メッセージ][message]の中でチェックされる情報の位置を示します。 + * 2番目の要素は *演算子* です。これは、ターゲットパスで示された情報をどのようにチェックするかを示します。 + * 3番目の要素は *演算子のための引数* です。これは、プリミティブ値(文字列、数値、または真偽値)、もしくはそれらの値の配列です。ただし、いくつかの演算子は引数を取りません。 + +#### ターゲットパス {#syntax-basic-target-path} + +ターゲットパスは以下の文字列のような形で示します: + + "body.success" + +Droonga Engineのマッチング機構は、これをドットで区切られた *パスコンポーネント* のリストとして解釈します。 +1つのパスコンポーネントはメッセージ中の同名のプロパティを表します。 +よって、上記の例は以下の位置を示します: + + { + "body": { + "success": <target> + } + } + + + + +#### 利用可能な演算子 {#syntax-basic-operators} + +演算子はシンボルとして指定します。 + +`:equal` +: ターゲットの値が与えられた値と等しい場合に `true` を返します。それ以外の場合は `false` を返します。 + 例えば、 + + ["type", :equal, "search"] + + 上記のパターンは以下のようなメッセージにマッチします: + + { + "type": "search", + ... + } + +`:in` +: ターゲットの値が与えられた配列の中に含まれている場合に `true` を返します。それ以外の場合は `false` を返します。 + 例えば、 + + ["type", :in, ["search", "select"]] + + 上記のパターンは以下のようなメッセージにマッチします: + + { + "type": "select", + ... + } + + 以下にはマッチしません: + + { + "type": "find", + ... + } + +`:include` +: ターゲットの値の配列の中に指定された値が含まれている場合に `true` を返します。それ以外の場合は `false` を返します。 + 言い換えると、これは `:in` 演算子の反対の働きをします。 + 例えば、 + + ["body.tags", :include, "News"] + + 上記のパターンは以下のようなメッセージにマッチします: + + { + "type": "my.notification", + "body": { + "tags": ["News", "Groonga", "Droonga", "Fluentd"] + } + } + +`:exist` +: ターゲットに指定された情報が存在する場合は `true` を返します。それ以外の場合は `false` を返します。 + 例えば、 + + ["body.comments", :exist, "News"] + + 上記のパターンは以下のようなメッセージにマッチします: + + { + "type": "my.notification", + "body": { + "title": "Hello!", + "comments": [] + } + } + + 以下にはマッチしません: + + { + "type": "my.notification", + "body": { + "title": "Hello!" + } + } + +`:start_with` +: ターゲットの文字列が指定された文字列で始まる場合に `true` を返します。それ以外の場合は `false` を返します。 + 例えば、 + + ["body.path", :start_with, "/archive/"] + + 上記のパターンは以下のようなメッセージにマッチします: + + { + "type": "my.notification", + "body": { + "path": "/archive/2014/02/28.html" + } + } + + +### ネストしたパターン {#syntax-nested} + +#### 構造 {#syntax-nested-structure} + +ネストしたパターンは、以下のような3つの要素を持つ配列として表現されます: + + [ + ["type", :equal, "table_create"], + :or, + ["type", :equal, "column_create"] + ] + + * 最初の要素と最後の要素は基本パターンまたはネストしたパターンです。(言い換えると、ネストしたパターンは再帰的に書くことができます。) + * 2番目の要素は *論理演算子* です。 + +#### 利用可能な演算子 {#syntax-nested-operators} + +`:and` +: 与えられた両方のパターンが `true` を返す場合に、`true` を返します。それ以外の場合は `false` を返します。 + +`:or` +: 与えられたパターン(1番目または3番目の要素)のいずれかまたは両方が `true` を返す場合に `true` を返します。それ以外の場合は `false` を返します。 + + + + + [message]:../../message/ + Added: ja/tutorial/1.1.2/add-replica/index.md (+400 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/add-replica/index.md 2015-11-15 23:29:56 +0900 (6544be6) @@ -0,0 +1,400 @@ +--- +title: "Droongaチュートリアル: 既存クラスタへのreplicaの追加" +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/add-replica/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## チュートリアルのゴール + +既存の[Droonga][]クラスタについて、新しいreplicaを追加し、既存のreplicaを削除し、および、既存のreplicaを新しいreplicaで置き換えるための手順を学ぶこと。 + +## 前提条件 + +* 何らかのデータが格納されている状態の[Droonga][]クラスタがあること。 + このチュートリアルを始める前に、[「使ってみる」のチュートリアル](../groonga/)を完了しておいて下さい。 +* 複数のクラスタの間でのデータの複製方法を把握していること。 + このチュートリアルを始める前に、[バックアップと復元のチュートリアル](../dump-restore/)を完了しておいて下さい。 + +このチュートリアルでは、[最初のチュートリアル](../groonga/)で準備した2つの既存のDroongaノード:`node0` (`192.168.100.50`) 、 `node1` (`192.168.100.51`) と、新しいノードとして使うもう1台のコンピュータ `node2` (`192.168.100.52`) があると仮定します。 +あなたの手元にあるDroongaノードがこれとは異なる名前である場合には、以下の説明の中の`node0`、`node1`、`node2`は実際の物に読み替えて下さい。 + +## 「replica」とは? + +Droongaのノードの集合には、「replica」と「slice」という2つの軸があります。 + +「replica」のノード群は、完全に同一のデータを持っており、検索などのリクエストを各ノードが並行して処理する事ができます。 +新しいreplicaを追加する事によって、増加するリクエストに対して処理能力を増強することができます。 + +他方、「slice」のノード群はそれぞれ異なるデータを持ちます(例えば、あるノードは2013年のデータ、別のノードは2014年のデータ、という具合です)。 +新しいsliceを追加する事によって、増大するデータ量に対してクラスタとしての容量を拡大することができます。 + +現在の所、Groonga互換のシステムとして設定されたDroongaクラスタについては、replicaを追加することはできますが、sliceを追加することはできません。 +この点については将来のバージョンで改善する予定です。 + +ともかく、このチュートリアルでは既存のDroongaクラスタに新しいreplicaを追加する手順を解説します。 +早速始めましょう。 + +## 既存のクラスタに新しいreplicaノードを追加する + +*クラスタへのreplicaノードの「Hot-Add」(サービスのダウンタイム無しでクラスタ構成を動的に変更すること。この場合はreplicaの動的な追加)を行うためには、クラスタ内に2つ以上の既存replicaが存在している必要があります。* +この操作の進行中は、既存のreplicaのうち1つが新しいreplicaに対する「データのコピー元」となり、それ以外のノードがサービスを提供することになります。 + +クラスタ内に既存のreplicaが1つしかない場合には、cronjobによるバッチ処理、クローラなどの*データベースに対する変更操作を、操作が完了するまでの間全て停止しておく必要があります*。 +でないと、追加したreplicaと既存のreplicaの内容に不整合が発生します。 +以下は、データベースに変更を加える代表的な組み込みのコマンドの一覧です: + + * `add` + * `column_create` + * `column_remove` + * `delete` + * `load` + * `table_create` + * `table_remove` + +ただし、既存のデータに一切変更を加えない種類のメッセージ(`search`や`sytem.status`など)については、この操作の間も利用できます。 +端的に言うと、既存のreplicaが1つだけしかない場合は、*新しいreplicaを追加する操作の間はクローリングを停止する必要がある*、という事ですね。 + +ここでは、`node0` と `node1` の2つのreplicaノードからなるDroongaクラスタがあり、新しいreplicaノードとして `node2` を追加すると仮定します。 + +### 新しいノードをセットアップする + +まず、新しいコンピュータをセットアップし、必要なソフトウェアのインストールと設定を済ませます。 + +~~~ +(on node2) +# curl https://raw.githubusercontent.com/droonga/droonga-engine/master/install.sh | \ + HOST=node2 bash +# curl https://raw.githubusercontent.com/droonga/droonga-http-server/master/install.sh | \ + ENGINE_HOST=node2 HOST=node2 bash +~~~ + +注意点として、空でないノードを既存のクラスタに追加することはできません。 +もしそのコンピュータがかつてDroongaノードとして使われていた事があった場合には、最初に古いデータを消去する必要があります。 + +~~~ +(on node2) +# droonga-engine-configure --quiet \ + --clear --reset-config --reset-catalog \ + --host=node2 +# droonga-http-server-configure --quiet --reset-config \ + --droonga-engine-host-name=node2 \ + --receive-host-name=node2 +~~~ + +では、サービスを起動しましょう。 + +~~~ +(on node2) +# service droonga-engine start +# service droonga-http-server start +~~~ + +この時点で、この新しいノードは既存のクラスタのノードとしては動作していません。 +この事は、`system.status`コマンドを通じて確認できます: + +~~~ +$ curl "http://node0:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +$ curl "http://node2:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node2:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +~~~ + +### 継続的に流入するメッセージの準備 + +[前の項目](../dump-restore/)に引き続いてこのチュートリアルを順番に読み進めている場合、クラスタに対してはデータの流入がまだ無い状態になっているはずです。 +Hot-Addを試してみるために、以下のようにして、継続的に新しいレコードを追加する仮想的なデータソースを準備しましょう: + +~~~ +(on node0) +$ count=0; maxcount=500; \ + while [ "$count" -lt "$maxcount" ]; \ + do \ + droonga-add --host node0 --table Store --key "dummy-store$count" --name "Dummy Store $count"; \ + count=$(($count + 1)); \ + sleep 1; \ + done +~~~ + +これは、合計で500件のレコードを1秒ごとに1レコードずつ追加する例です。 +[`droonga-add`はDroongaが提供しているコマンドラインユーティリティです][droonga-add-command]が、今のところは詳細について理解していなくてもも大丈夫です。 + +### 新しいreplicaをクラスタに参加させる + +既存のクラスタに新しいreplicaを追加するには、いずれかの既存のreplicaまたは新しく追加するreplicaの上で、[`droonga-engine-join`というコマンド][droonga-engine-join-command]を以下のようにして実行します: + +~~~ +(on node2) +$ droonga-engine-join --host=node2 \ + --replica-source-host=node0 \ + --receiver-host=node2 +Start to join a new node node2 + to the cluster of node0 + via node2 (this host) + port = 10031 + tag = droonga + dataset = Default + +Source Cluster ID: 8951f1b01583c1ffeb12ed5f4093210d28955988 + +Changing role of the joining node... +Configuring the joining node as a new replica for the cluster... +Registering new node to existing nodes... +Changing role of the source node... +Getting the timestamp of the last processed message in the source node... +The timestamp of the last processed message at the source node: xxxx-xx-xxTxx:xx:xx.xxxxxxZ +Setting new node to ignore messages older than the timestamp... +Copying data from the source node... +100% done (maybe 00:00:00 remaining) +Restoring role of the source node... +Restoring role of the joining node... +Done. +~~~ + +このコマンドは、以下のようにして別のノード上で実行することもできます: + +~~~ +(on node1) +$ droonga-engine-join --host=node2 \ + --replica-source-host=node0 \ + --receiver-host=node1 +Start to join a new node node2 + to the cluster of node0 + via node1 (this host) +... +~~~ + + * `--host` オプションで、その新しいreplicaノードのホスト名(またはIPアドレス)を指定して下さい。 + * `--replica-source-host` オプションで、クラスタ中の既存のノードの1つのホスト名(またはIPアドレス)を指定して下さい。 + * `--receiver-host` オプションで、コマンドを実行しているマシン自身のホスト名(またはIPアドレス)を必ず指定して下さい。 + +すると、このコマンドは自動的にクラスタ内のデータを新しいreplicaに同期し始めます。 +全てのデータを無事に同期し終えたら、新しいノードはクラスタのreplicaとしてそのまま働き始めます。 + +以上の操作で、新しいreplicaノードがDroongaクラスタへ無事に追加されました。 +`system.status`コマンドを使って、これらのノードがクラスタとして動作していることを確かめましょう: + +~~~ +$ curl "http://node0:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + }, + "node2:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +~~~ + +新しいノード`node2`がクラスタに参加したため、各ノードの`droonga-http-server`は自動的に、メッセージを`node2`にも分配するようになります。 + +全てのreplicaが同等になっているかどうかは、`system.statistics.object.count.per-volume`を使って以下のように確かめられます: + +~~~ +(on node0) +$ curl "http://node0:10041/droonga/system/statistics/object/count/per-volume?output\[\]=total" | jq "." +{ + "node0:10031/droonga.000": { + "total": 540 + }, + "node1:10031/droonga.000": { + "total": 540 + }, + "node2:10031/droonga.000": { + "total": 540 + } +} +~~~ + +出力されている数値は、各ノードのデータベースに何個のオブジェクトが保持されているかを示しています。 +全ての値が同じなので、各レプリカはお互いに同等の状態になっているということが分かります。 + + +## 既存のクラスタからreplicaノードを削除する + +Droongaノードは、メモリ不足、ディスク容量不足、ハードウェア障害など、様々な致命的な理由によって動作しなくなり得ます。 +Droongaクラスタ内のノードは互いに監視しあっており、動作しなくなったノードに対してはメッセージの配送を自動的に停止して、動作しないノードがあってもクラスタ全体としては動作し続けるようになっています。 +このような時には、動作していないノードを取り除く必要があります。 + +もちろん、他の目的に転用したいといった理由から、正常動作中のノードを取り除きたいと考える場合もあるでしょう。 + +ここでは、`node0` 、 `node1` 、`node2` の3つのreplicaノードからなるDroongaクラスタがあり、最後のノード `node2` をクラスタから離脱させようとしていると仮定します。 + +### 既存のreplicaをクラスタから分離する + +replicaノードを既存のクラスタから削除するには、クラスタ内のいずれかのノードの上で、以下のようにして[`droonga-engine-unjoin`コマンド][droonga-engine-unjoin-command]を実行します: + +~~~ +(on node0) +$ droonga-engine-unjoin --host=node2 \ + --receiver-host=node0 +Start to unjoin a node node2:10031/droonga + by node0 (this host) + +Unjoining replica from the cluster... +Done. +~~~ + + * `--host` オプションで、クラスタから削除するノードのホスト名(またはIPアドレス)を指定して下さい。 + * `--receiver-host` オプションで、コマンドを実行しているマシン自身のホスト名(またはIPアドレス)を必ず指定して下さい。 + +すると、指定されたノードがクラスタから自動的に離脱します。 + +これで、ノードのクラスタからの切り離しは無事に完了しました。 +`node2`が本当にクラスタから離脱しているかどうかは、`system.status コマンドを使って以下のように確かめられます: + +~~~ +$ curl "http://node0:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +$ curl "http://node2:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node2:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +~~~ + +ノード`node2`はもはやクラスタの一員ではないため、`node0`と`node1`の`droonga-http-server`は`node2`の`droonga-engine`へはもうメッセージを送りません。 +またその一方で、`node2`の`droonga-http-server`はそのノード上の`droonga-engine`にのみ関連付けられており、他のノードへはメッセージを送りません。 + + + +## クラスタ内の既存のreplicaノードを新しいreplicaノードで置き換える + +ノードの置き換えは、上記の手順の組み合わせで行います。 + +ここでは、`node0` と `node1` の2つのreplicaノードからなるDroongaクラスタがあり、`node1` が不安定で、それを新しいreplicaノード `node2` で置き換えようとしていると仮定します。 + +### 既存のreplicaをクラスタから分離する + +まず、不安定になっているノードを取り除きます。以下のようにしてクラスタからノードを離脱させて下さい: + +~~~ +(on node0) +$ droonga-engine-unjoin --host=node1 +~~~ + +これで、ノードがクラスタから離脱しました。この事は `system.status` コマンドで確かめられます: + +~~~ +$ curl "http://node0:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node0:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +~~~ + +### 新しいreplicaを追加する + +次に、新しいreplica `node2`を用意します。 +必要なパッケージをインストールし、`catalog.json`を生成して、サービスを起動します。 + +~~~ +(on node2) +# curl https://raw.githubusercontent.com/droonga/droonga-engine/master/install.sh | \ + HOST=node2 bash +# curl https://raw.githubusercontent.com/droonga/droonga-http-server/master/install.sh | \ + ENGINE_HOST=node2 HOST=node2 bash +~~~ + +そのコンピュータがかつてDroongaノードの一員だったことがある場合は、インストール作業の代わりに、古いデータを消去する必要があります: + +~~~ +(on node2) +# droonga-engine-configure --quiet \ + --clear --reset-config --reset-catalog \ + --host=node2 +# droonga-http-server-configure --quiet --reset-config \ + --droonga-engine-host-name=node2 \ + --receive-host-name=node2 +~~~ + +そうしたら、そのノードをクラスタに参加させましょう。 + +~~~ +(on node2) +$ droonga-engine-join --host=node2 \ + --replica-source-host=node0 +~~~ + +最終的に、`node0` と `node2` の2つのノードからなるDroongaクラスタができあがりました。 + +この事は、`system.status` コマンドの結果を見ると確認できます: + +~~~ +$ curl "http://node0:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node2:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +~~~ + +## まとめ + +このチュートリアルでは、既存の[Droonga][]クラスタに新しいreplicaノードを追加する方法を学びました。 +また、既存のreplicaを取り除く方法と、既存のreplicaを新しいreplicaで置き換える方法も学びました。 + + [Ubuntu]: http://http://ubuntulinux.jp/ + [Droonga]: https://droonga.org/ja/ + [Groonga]: http://groonga.org/ja/ + [drndump-command]: /ja/reference/command-line-tools/drndump/ + [droonga-add-command]: /ja/reference/command-line-tools/droonga-add/ + [droonga-engine-join-command]: /ja/reference/command-line-tools/droonga-engine-join/ + [droonga-engine-unjoin-command]: /ja/reference/command-line-tools/droonga-engine-unjoin/ Added: ja/tutorial/1.1.2/basic/index.md (+1126 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/basic/index.md 2015-11-15 23:29:56 +0900 (f736c6b) @@ -0,0 +1,1126 @@ +--- +title: "Droonga チュートリアル: 低レイヤのコマンドの基本的な使い方" +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/basic/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## チュートリアルのゴール + +Droonga の低レイヤのコマンドを用いて、Droonga を使った検索システムを自分で構築できるようになる。 + +## 前提条件 + +* [Ubuntu][] または [CentOS][] の Server を自分でセットアップしたり、基本的な操作ができること +* [Ruby][] と [Node.js][] の基本的な知識があること + +## 概要 + +### Droonga とは + +分散データ処理エンジンです。 "distributed-groonga" に由来します。 + +Droonga は複数のコンポーネントから構成されています。ユーザは、これらのパッケージを組み合わせて利用することで、全文検索をはじめとするスケーラブルな分散データ処理システムを構築することができます。 + +### Droonga を構成するコンポーネント + +#### Droonga Engine + +Droonga Engine は Droonga における分散データ処理の要となるコンポーネントです。リクエストに基いて実際のデータ処理を行います。 + +このコンポーネントは[droonga-engine][]という名前で開発およびリリースされています。 +通信に使用するプロトコルは[Fluentd]と互換性があります。 + +[droonga-engine][] は検索エンジンとして、オープンソースのカラムストア機能付き全文検索エンジン [Groonga][] を使用しています。 + +#### Protocol Adapter + +Protocol Adapter は、Droonga を様々なプロトコルで利用できるようにするためのコンポーネントです。 + +Droonga Engine自体は通信プロトコルとしてfluentdプロトコルにのみ対応しています。 +その代わりに、Protocol AdapterがDroonga Engineとクライアントの間に立って、fluentdプロトコルと他の一般的なプロトコル(HTTP、Socket.IOなど)とを翻訳することになります。 + +現在の所、HTTP用の実装として、[Node.js][]用モジュールパッケージの[droonga-http-server][]が存在しています。 +言い直すと、droonga-http-serverはDroonga Protocol Adapterの一実装で、言わば「Droonga HTTP Protocol Adapter」であるという事です。 + +## チュートリアルでつくるシステムの全体像 + +チュートリアルでは、以下の様な構成のシステムを構築します。 + + +-------------+ +------------------+ +----------------+ + | Web Browser | <--------> | Protocol Adapter | <-------> | Droonga Engine | + +-------------+ HTTP +------------------+ Fluent +----------------+ + w/droonga-http protocol w/droonga-engine + -server + + + \--------------------------------------------------/ + この部分を構築します + +ユーザは Protocol Adapter に、Web ブラウザなどを用いて接続します。Protocol Adapter は Droonga Engine へリクエストを送信します。実際の検索処理は Droonga Engine が行います。検索結果は、Droonga Engine から Protocol Adapter に渡され、最終的にユーザに返ります。 + +例として、[ニューヨークにあるスターバックスの店舗](http://geocommons.com/overlays/430038)を検索できるデータベースシステムを作成することにします。 + + +## 実験用のマシンを用意する + +まずコンピュータを調達しましょう。このチュートリアルでは、既存のコンピュータにDroongaによる検索システムを構築する手順を解説します。 +以降の説明は基本的に、[DigitalOcean](https://www.digitalocean.com/)で `Ubuntu 14.04 x64`、`CentOS 6.5 x64`、 または `CentOS 7 x64` の仮想マシンのセットアップを完了し、コンソールにアクセスできる状態になった後を前提として進めます。 + +注意:Droongaが必要とするパッケージをインストールする前に、マシンが2GB以上のメモリを備えていることを確認して下さい。メモリが不足していると、パッケージのインストール中にネイティブ拡張のビルドに失敗する場合があります。 + +ホストが `192.168.100.50` だと仮定します。 + +### Droonga Engineをインストールする + +Droonga Engine は、データベースを保持し、実際の検索を担当する部分です。 +このセクションでは、 droonga-engine をインストールし、検索対象となるデータを準備します。 + +### `droonga-engine`をインストールする + +インストールスクリプトをダウンロードし、root権限で`bash`で実行して下さい: + +~~~ +# curl https://raw.githubusercontent.com/droonga/droonga-engine/master/install.sh | \ + bash +... +Installing droonga-engine from RubyGems... +... +Preparing the user... +... +Setting up the configuration directory... +This node is configured with a hostname XXXXXXXX. + +Registering droonga-engine as a service... +... +Successfully installed droonga-engine. +~~~ + +### `droonga-engine`を起動するための設定ファイルを用意する + +すべての設定ファイルと物理的なデータベースは、`droonga-engine`サービス用のユーザのホームディレクトリ内にある`droonga`ディレクトリの下に置かれます: + + $ cd ~droonga-engine/droonga + +では、以下の内容で設定ファイル `catalog.json` を上書きしましょう: + +catalog.json: + + { + "version": 2, + "effectiveDate": "2013-09-01T00:00:00Z", + "datasets": { + "Default": { + "nWorkers": 4, + "plugins": ["groonga", "crud", "search", "dump", "status"], + "schema": { + "Store": { + "type": "Hash", + "keyType": "ShortText", + "columns": { + "location": { + "type": "Scalar", + "valueType": "WGS84GeoPoint" + } + } + }, + "Location": { + "type": "PatriciaTrie", + "keyType": "WGS84GeoPoint", + "columns": { + "store": { + "type": "Index", + "valueType": "Store", + "indexOptions": { + "sources": ["location"] + } + } + } + }, + "Term": { + "type": "PatriciaTrie", + "keyType": "ShortText", + "normalizer": "NormalizerAuto", + "tokenizer": "TokenBigram", + "columns": { + "stores__key": { + "type": "Index", + "valueType": "Store", + "indexOptions": { + "position": true, + "sources": ["_key"] + } + } + } + } + }, + "replicas": [ + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { + "volume": { + "address": "192.168.100.50:10031/droonga.000" + } + }, + { + "volume": { + "address": "192.168.100.50:10031/droonga.001" + } + }, + { + "volume": { + "address": "192.168.100.50:10031/droonga.002" + } + } + ] + }, + { + "dimension": "_key", + "slicer": "hash", + "slices": [ + { + "volume": { + "address": "192.168.100.50:10031/droonga.010" + } + }, + { + "volume": { + "address": "192.168.100.50:10031/droonga.011" + } + }, + { + "volume": { + "address": "192.168.100.50:10031/droonga.012" + } + } + ] + } + ] + } + } + } + +この`catalog.json`では、データセット`Starbucks`を以下のように定義しています: + + * 最上位には1つのボリュームがあり、このボリュームには「レプリカ」と名付けられた2つのサブボリュームが含まれる。 + * 1段階下がった次のレベルには、1つのレプリカ・ボリュームごとに「スライス」と名付けられた3つのサブボリュームが含まれる。 + これらはDroongaのデータセットの最小の構成要素である。 + +これらの6つの、`"address"`の情報を持つ最小単位のボリュームは、内部的に*シングル・ボリューム*と呼ばれます。 +`"address"`の情報は、対応する物理的なストレージであるGroongaのデータベースの位置を示していて、それらのデータベースは`droonga-engine`によって自動的に作成されます。 + +`catalog.json` の詳細については [catalog.json](/ja/reference/catalog) を参照してください。 + +### `droonga-engine`サービスの起動と終了 + +`droonga-engine`サービスは`service`コマンドを使って起動できます: + +~~~ +# service droonga-engine start +~~~ + +終了する場合も、`service`コマンドを使います: + +~~~ +# service droonga-engine stop +~~~ + +確認できたら、再び`droonga-engine`を起動します。 + +~~~ +# service droonga-engine start +~~~ + +### データベースを作成する + +Dronga Engine が起動したので、データを投入しましょう。 +店舗のデータ `stores.jsons` を用意します。 + +stores.jsons: + +~~~ +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "1st Avenue & 75th St. - New York NY (W)", + "values": { + "location": "40.770262,-73.954798" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "76th & Second - New York NY (W)", + "values": { + "location": "40.771056,-73.956757" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "2nd Ave. & 9th Street - New York NY", + "values": { + "location": "40.729445,-73.987471" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "15th & Third - New York NY (W)", + "values": { + "location": "40.733946,-73.9867" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "41st and Broadway - New York NY (W)", + "values": { + "location": "40.755111,-73.986225" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "84th & Third Ave - New York NY (W)", + "values": { + "location": "40.777485,-73.954979" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "150 E. 42nd Street - New York NY (W)", + "values": { + "location": "40.750784,-73.975582" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "West 43rd and Broadway - New York NY (W)", + "values": { + "location": "40.756197,-73.985624" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "Macy's 35th Street Balcony - New York NY", + "values": { + "location": "40.750703,-73.989787" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "Macy's 6th Floor - Herald Square - New York NY (W)", + "values": { + "location": "40.750703,-73.989787" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "Herald Square- Macy's - New York NY", + "values": { + "location": "40.750703,-73.989787" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "Macy's 5th Floor - Herald Square - New York NY (W)", + "values": { + "location": "40.750703,-73.989787" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "80th & York - New York NY (W)", + "values": { + "location": "40.772204,-73.949862" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "Columbus @ 67th - New York NY (W)", + "values": { + "location": "40.774009,-73.981472" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "45th & Broadway - New York NY (W)", + "values": { + "location": "40.75766,-73.985719" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "Marriott Marquis - Lobby - New York NY", + "values": { + "location": "40.759123,-73.984927" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "Second @ 81st - New York NY (W)", + "values": { + "location": "40.77466,-73.954447" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "52nd & Seventh - New York NY (W)", + "values": { + "location": "40.761829,-73.981141" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "1585 Broadway (47th) - New York NY (W)", + "values": { + "location": "40.759806,-73.985066" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "85th & First - New York NY (W)", + "values": { + "location": "40.776101,-73.949971" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "92nd & 3rd - New York NY (W)", + "values": { + "location": "40.782606,-73.951235" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "165 Broadway - 1 Liberty - New York NY (W)", + "values": { + "location": "40.709727,-74.011395" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "1656 Broadway - New York NY (W)", + "values": { + "location": "40.762434,-73.983364" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "54th & Broadway - New York NY (W)", + "values": { + "location": "40.764275,-73.982361" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "Limited Brands-NYC - New York NY", + "values": { + "location": "40.765219,-73.982025" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "19th & 8th - New York NY (W)", + "values": { + "location": "40.743218,-74.000605" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "60th & Broadway-II - New York NY (W)", + "values": { + "location": "40.769196,-73.982576" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "63rd & Broadway - New York NY (W)", + "values": { + "location": "40.771376,-73.982709" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "195 Broadway - New York NY (W)", + "values": { + "location": "40.710703,-74.009485" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "2 Broadway - New York NY (W)", + "values": { + "location": "40.704538,-74.01324" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "2 Columbus Ave. - New York NY (W)", + "values": { + "location": "40.769262,-73.984764" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "NY Plaza - New York NY (W)", + "values": { + "location": "40.702802,-74.012784" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "36th and Madison - New York NY (W)", + "values": { + "location": "40.748917,-73.982683" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "125th St. btwn Adam Clayton & FDB - New York NY", + "values": { + "location": "40.808952,-73.948229" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "70th & Broadway - New York NY (W)", + "values": { + "location": "40.777463,-73.982237" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "2138 Broadway - New York NY (W)", + "values": { + "location": "40.781078,-73.981167" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "118th & Frederick Douglas Blvd. - New York NY (W)", + "values": { + "location": "40.806176,-73.954109" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "42nd & Second - New York NY (W)", + "values": { + "location": "40.750069,-73.973393" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "Broadway @ 81st - New York NY (W)", + "values": { + "location": "40.784972,-73.978987" + } + } +} +{ + "dataset": "Default", + "type": "add", + "body": { + "table": "Store", + "key": "Fashion Inst of Technology - New York NY", + "values": { + "location": "40.746948,-73.994557" + } + } +} +~~~ + +もう一つターミナルを開いて、jsonをDroonga engineに送信しましょう。 + +以下のようにして`stores.json`を送信します: + +~~~ +$ droonga-request stores.jsons +Elapsed time: 0.01101195 +[ + "droonga.message", + 1393562553, + { + "inReplyTo": "1393562553.8918273", + "statusCode": 200, + "type": "add.result", + "body": true + } +] +... +Elapsed time: 0.004817463 +[ + "droonga.message", + 1393562554, + { + "inReplyTo": "1393562554.2447524", + "statusCode": 200, + "type": "add.result", + "body": true + } +] +~~~ + +Droonga engineを用いてスターバックスの店舗データベースを検索する準備ができました。 + +### droonga-requestでリクエストを送る + +動作を確認してみましょう。クエリを以下のようなJSONファイルとして作成します。 + +search-all-stores.json: + +~~~ +{ + "dataset": "Default", + "type": "search", + "body": { + "queries": { + "stores": { + "source": "Store", + "output": { + "elements": [ + "startTime", + "elapsedTime", + "count", + "attributes", + "records" + ], + "attributes": ["_key"], + "limit": -1 + } + } + } + } +} +~~~ + +Droonga Engine にリクエストを送信します: + +~~~ +$ droonga-request search-all-stores.json +Elapsed time: 0.008286785 +[ + "droonga.message", + 1393562604, + { + "inReplyTo": "1393562604.4970381", + "statusCode": 200, + "type": "search.result", + "body": { + "stores": { + "count": 40, + "records": [ + [ + "15th & Third - New York NY (W)" + ], + [ + "41st and Broadway - New York NY (W)" + ], + [ + "84th & Third Ave - New York NY (W)" + ], + [ + "Macy's 35th Street Balcony - New York NY" + ], + [ + "Second @ 81st - New York NY (W)" + ], + [ + "52nd & Seventh - New York NY (W)" + ], + [ + "1585 Broadway (47th) - New York NY (W)" + ], + [ + "54th & Broadway - New York NY (W)" + ], + [ + "60th & Broadway-II - New York NY (W)" + ], + [ + "63rd & Broadway - New York NY (W)" + ], + [ + "2 Columbus Ave. - New York NY (W)" + ], + [ + "NY Plaza - New York NY (W)" + ], + [ + "2138 Broadway - New York NY (W)" + ], + [ + "Broadway @ 81st - New York NY (W)" + ], + [ + "76th & Second - New York NY (W)" + ], + [ + "2nd Ave. & 9th Street - New York NY" + ], + [ + "150 E. 42nd Street - New York NY (W)" + ], + [ + "Macy's 6th Floor - Herald Square - New York NY (W)" + ], + [ + "Herald Square- Macy's - New York NY" + ], + [ + "Macy's 5th Floor - Herald Square - New York NY (W)" + ], + [ + "Marriott Marquis - Lobby - New York NY" + ], + [ + "85th & First - New York NY (W)" + ], + [ + "1656 Broadway - New York NY (W)" + ], + [ + "Limited Brands-NYC - New York NY" + ], + [ + "2 Broadway - New York NY (W)" + ], + [ + "36th and Madison - New York NY (W)" + ], + [ + "125th St. btwn Adam Clayton & FDB - New York NY" + ], + [ + "118th & Frederick Douglas Blvd. - New York NY (W)" + ], + [ + "Fashion Inst of Technology - New York NY" + ], + [ + "1st Avenue & 75th St. - New York NY (W)" + ], + [ + "West 43rd and Broadway - New York NY (W)" + ], + [ + "80th & York - New York NY (W)" + ], + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "45th & Broadway - New York NY (W)" + ], + [ + "92nd & 3rd - New York NY (W)" + ], + [ + "165 Broadway - 1 Liberty - New York NY (W)" + ], + [ + "19th & 8th - New York NY (W)" + ], + [ + "195 Broadway - New York NY (W)" + ], + [ + "70th & Broadway - New York NY (W)" + ], + [ + "42nd & Second - New York NY (W)" + ] + ] + } + } + } +] +~~~ + +店舗の名前が取得できました。エンジンは正しく動作しているようです。引き続き Protocol Adapter を構築して、検索リクエストをHTTPで受け付けられるようにしましょう。 + +## HTTP Protocol Adapter を用意する + +HTTP Protocol Adapterとして`droonga-http-server`を使用しましょう。 + +### droonga-http-serverをインストールする + +インストールスクリプトをダウンロードし、root権限で`bash`で実行して下さい: + +~~~ +# curl https://raw.githubusercontent.com/droonga/droonga-http-server/master/install.sh | \ + bash +... +Installing droonga-http-server from npmjs.org... +... +Preparing the user... +... +Setting up the configuration directory... +The droonga-engine service is detected on this node. +The droonga-http-server is configured to be connected +to this node (XXXXXXXX). +This node is configured with a hostname XXXXXXXX. + +Registering droonga-http-server as a service... +... +Successfully installed droonga-http-server. +~~~ + +### `droonga-engine`サービスの起動と終了 + +`droonga-http-server`サービスは`service`コマンドを使って起動できます: + +~~~ +# service droonga-http-server start +~~~ + +終了する場合も、`service`コマンドを使います: + +~~~ +# service droonga-http-server stop +~~~ + +確認できたら、再び`droonga-http-server`を起動します。 + +~~~ +# service droonga-engine start +~~~ + +### HTTPでの検索リクエスト + +準備が整いました。 Protocol Adapter に向けて HTTP 経由でリクエストを発行し、データベースに問い合わせを行ってみましょう。まずは `Shops` テーブルの中身を取得してみます。以下のようなリクエストを用います。(`attributes=_key` を指定しているのは「検索結果に `_key` 値を含めて返してほしい」という意味です。これがないと、`records` に何も値がないレコードが返ってきてしまいます。`attributes` パラメータには `,` 区切りで複数の属性を指定することができます。`attributes=_key,location` と指定することで、緯度経度もレスポンスとして受け取ることができます) + + $ curl "http://192.168.100.50:10041/tables/Store?attributes=_key&limit=-1" + { + "stores": { + "count": 40, + "records": [ + [ + "15th & Third - New York NY (W)" + ], + [ + "41st and Broadway - New York NY (W)" + ], + [ + "84th & Third Ave - New York NY (W)" + ], + [ + "Macy's 35th Street Balcony - New York NY" + ], + [ + "Second @ 81st - New York NY (W)" + ], + [ + "52nd & Seventh - New York NY (W)" + ], + [ + "1585 Broadway (47th) - New York NY (W)" + ], + [ + "54th & Broadway - New York NY (W)" + ], + [ + "60th & Broadway-II - New York NY (W)" + ], + [ + "63rd & Broadway - New York NY (W)" + ], + [ + "2 Columbus Ave. - New York NY (W)" + ], + [ + "NY Plaza - New York NY (W)" + ], + [ + "2138 Broadway - New York NY (W)" + ], + [ + "Broadway @ 81st - New York NY (W)" + ], + [ + "76th & Second - New York NY (W)" + ], + [ + "2nd Ave. & 9th Street - New York NY" + ], + [ + "150 E. 42nd Street - New York NY (W)" + ], + [ + "Macy's 6th Floor - Herald Square - New York NY (W)" + ], + [ + "Herald Square- Macy's - New York NY" + ], + [ + "Macy's 5th Floor - Herald Square - New York NY (W)" + ], + [ + "Marriott Marquis - Lobby - New York NY" + ], + [ + "85th & First - New York NY (W)" + ], + [ + "1656 Broadway - New York NY (W)" + ], + [ + "Limited Brands-NYC - New York NY" + ], + [ + "2 Broadway - New York NY (W)" + ], + [ + "36th and Madison - New York NY (W)" + ], + [ + "125th St. btwn Adam Clayton & FDB - New York NY" + ], + [ + "118th & Frederick Douglas Blvd. - New York NY (W)" + ], + [ + "Fashion Inst of Technology - New York NY" + ], + [ + "1st Avenue & 75th St. - New York NY (W)" + ], + [ + "West 43rd and Broadway - New York NY (W)" + ], + [ + "80th & York - New York NY (W)" + ], + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "45th & Broadway - New York NY (W)" + ], + [ + "92nd & 3rd - New York NY (W)" + ], + [ + "165 Broadway - 1 Liberty - New York NY (W)" + ], + [ + "19th & 8th - New York NY (W)" + ], + [ + "195 Broadway - New York NY (W)" + ], + [ + "70th & Broadway - New York NY (W)" + ], + [ + "42nd & Second - New York NY (W)" + ] + ] + } + } + +`count` の値からデータが全部で 36 件あることがわかります。`records` に配列として検索結果が入っています。 + +もう少し複雑なクエリを試してみましょう。例えば、店名に「Columbus」を含む店舗を検索します。`query` パラメータにクエリ `Columbus` を、`match_to` パラメータに検索対象として `_key` を指定し、以下のようなリクエストを発行します。 + + $ curl "http://192.168.100.50:10041/tables/Store?query=Columbus&match_to=_key&attributes=_key&limit=-1" + { + "stores": { + "count": 2, + "records": [ + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "2 Columbus Ave. - New York NY (W)" + ] + ] + } + } + +以上 2 件が検索結果として該当することがわかりました。 + +Droonga HTTP Serverの詳細については[リファレンスマニュアル][http-server]を参照して下さい。 + + +## まとめ + +[Ubuntu Linux][Ubuntu] または [CentOS][] 上に [Droonga][] を構成するパッケージである [droonga-engine][] と [droonga-http-server][] をセットアップしました。 +これらのパッケージを利用することで、HTTP Protocol Adapter と Droonga Engine からなるシステムを構築し、実際に検索を行いました。 + + + [http-server]: ../../reference/http-server/ + [Ubuntu]: http://www.ubuntu.com/ + [CentOS]: https://www.centos.org/ + [Droonga]: https://droonga.org/ + [droonga-engine]: https://github.com/droonga/droonga-engine + [droonga-http-server]: https://github.com/droonga/droonga-http-server + [Groonga]: http://groonga.org/ + [Ruby]: http://www.ruby-lang.org/ + [nvm]: https://github.com/creationix/nvm + [Socket.IO]: http://socket.io/ + [Fluentd]: http://fluentd.org/ + [Node.js]: http://nodejs.org/ Added: ja/tutorial/1.1.2/benchmark/index.md (+811 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/benchmark/index.md 2015-11-15 23:29:56 +0900 (a40fd09) @@ -0,0 +1,811 @@ +--- +title: "DroongaとGroongaのベンチマークの取り方" +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/benchmark/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +<!-- +this is based on https://github.com/droonga/presentation-droonga-meetup-1-introduction/blob/master/benchmark/README.md +--> + +## チュートリアルのゴール + +[Droonga][]クラスタのベンチマークを測定し、[Groonga][groonga]での結果と比較するまでの、一連の手順を学ぶこと。 + +## 前提条件 + +* [Ubuntu][]または[CentOS][]のサーバの操作に関する基本的な知識と経験があること。 +* [Groonga][groonga]をHTTP経由で操作する際の基本的な知識と経験があること。 +* [Droonga][]クラスタの構築手順について基本的な知識があること。 + このチュートリアルの前に、[「使ってみる」のチュートリアル](../groonga/)を完了しておいて下さい。 + +## ベンチマークの必要性について + +DroongaはGroongaと互換性があるため、GroongaベースのアプリケーションをDroongaに移行することを検討することもあるでしょう。 +そんな時は、実際に移行する前に、Droongaの性能を測定して、より良い移行先であるかどうかを確認しておくべきです。 + +もちろん、単にGroongaとDroongaの性能差を知りたいと思うこともあるでしょう。 +ベンチマークによって、差を可視化することができます。 + + +### 性能の可視化の方法 + +あるシステムの性能を表す指標としては、以下の2つが多く使われます。 + + * レイテンシー + * スループット + +レイテンシーとは、システムがリクエストを受け取ってからレスポンスを返すまでに実際にかかった応答時間のことです。 +言い換えると、これは各リクエストについてクライアントが待たされた時間です。 +この指標においては、数値は小さければ小さいほどよいです。 +一般的に、クエリが軽い場合や、データベースのサイズが小さい場合、クライアント数が少ない場合に、レイテンシーは小さくなります。 + +スループットは、一度にどれだけの数のリクエストを捌けるかを意味するものです。 +性能の指標は「*クエリ毎秒*(Queries Per Second, *qps*)」という単位で表されます。 +例えば、あるGroongaサーバが1秒に10件のリクエストを処理できたとき、これを「10qps」と表現します。 +10人のユーザ(クライアント)がいるのかもしれませんし、2人のユーザがそれぞれブラウザ上で5つのタブを開いているのかもしれません。 +ともかく、「10qps」という数値は、1秒が経過する間にそのGroongaサーバが実際に10件のリクエストを受け付けて、レスポンスを返したということを意味します。 + +ベンチマークは、[drnbench]()というGemパッケージによって導入される`drnbench-request-response`コマンドで行うことができます。 +このツールは、計測対象のサービスについてレイテンシーとスループットの両方を計測できます。 + + +### ベンチマークツールはどのように性能を測定するのか + +`drnbench-request-response`は、対象サービスの性能を以下のようにして計測します: + + 1. マスタープロセスが仮想クライアントを1つ生成する。 + このクライアントは即座に動き始め、対象サービスに対して多数のリクエストを連続して頻繁に送り続ける。 + 2. しばらくしたら、マスタープロセスがクライアントを終了させる。 + そして、応答のデータから最小・最大・平均の経過時間を計算する。 + また、実際に対象サービスによって処理されたリクエストの件数を集計し、結果を1クライアントの場合のqps値として報告する。 + 3. マスタープロセスが仮想クライアントを2つ生成する。 + これらのクライアントはリクエストを送り始める。 + 4. しばらくしたら、マスタープロセスがすべてのクライアントを終了させる。 + そして、最小・最大・平均の経過時間を計算すると同時に、実際に対象サービスに処理されたリクエストの件数を集計し、結果を2クライアントの場合のqps値として報告する。 + 5. 3クライアントの場合、4クライアントの場合……と、クライアント数を増やしながら繰り返す。 + 6. 最後に、マスタープロセスが最小・最大・平均の経過時間、qps値、およびその他の情報をまとめたものを、以下のようなCSVファイルとして保存する: + + ~~~ + n_clients,total_n_requests,queries_per_second,min_elapsed_time,max_elapsed_time,average_elapsed_time,200 + 1,996,33.2,0.001773766,0.238031643,0.019765581680722916,100.0 + 2,1973,65.76666666666667,0.001558398,0.272225481,0.020047345673086702,100.0 + 4,3559,118.63333333333334,0.001531184,0.39942581,0.023357554419499882,100.0 + 6,4540,151.33333333333334,0.001540704,0.501663069,0.042344890696916264,100.0 + 8,4247,141.56666666666666,0.001483995,0.577100609,0.045836844514480835,100.0 + 10,4466,148.86666666666667,0.001987089,0.604507078,0.06949704923846833,100.0 + 12,4500,150.0,0.001782343,0.612596799,0.06902839555222215,100.0 + 14,4183,139.43333333333334,0.001980711,0.60754769,0.1033681068718623,100.0 + 16,4519,150.63333333333333,0.00284654,0.653204575,0.09473386513387955,100.0 + 18,4362,145.4,0.002330049,0.640683693,0.12581190483929405,100.0 + 20,4228,140.93333333333334,0.003710795,0.662666076,0.1301649290901133,100.0 + ~~~ + + この結果は、分析や、グラフ描画など、様々な使い方ができます。 + + (注意: 性能測定の結果は様々な要因によって変動します。 + これはあくまで特定のバージョン、特定の環境での結果の例です。) + +### 結果の読み方と分析の仕方 {#how-to-analyze} + +上の例を見て下さい。 + +#### HTTPレスポンスのステータス + +最後の列、`200`を見て下さい。 +これはHTTPレスポンスのステータスの割合を示しています。 +`200`は「OK」、`0`は「タイムアウト」です。 +`400`や`500`などのエラーレスポンスが得られた場合も、同様に報告されます。 +これらの情報は、意図しない速度低下の原因究明に役立つでしょう。 + +#### レイテンシー + +レイテンシーは簡単に分析できます。値が小さければ小さいほどよいと言えます。 +対象サービスのキャッシュ機構が正常に動作している場合、最小と平均の応答時間は小さくなります。 +最大応答時間は、重たいクエリ、システムのメモリのスワップの発生、意図しないエラーの発生などの影響を受けます。 + +レイテンシーのグラフは、有用な同時接続数の上限も明らかにします。 + + + +これは`average_elapsed_time`のグラフです。 +4クライアントを越えた所で経過時間が増加していることが見て取れるでしょう。 +これは何を意味するのでしょうか? + +Groongaは利用可能なプロセッサ数と同じ数だけのリクエストを完全に並行処理できます。 +コンピュータのプロセッサ数が4である場合、そのシステムは4件以下のリクエストについては余計な待ち時間無しで同時に処理することができます。 +それ以上の数のリクエストが来た場合、5番目以降のリクエストは、それ以前に受け付けたリクエストの処理完了後に処理されます。 +先のグラフは、この理論上の上限が事実であることを示しています。 + +#### スループット + +スループット性能の分析にも、グラフが便利です。 + + + +6クライアントを超えたあたりで、qps値が150前後で頭打ちになっているのを見て取れるでしょう。 +これは、計測対象のサービスが1秒あたり最大で150件のリクエストを処理できるということを意味しています。 + +言い直すと、この結果は「(ハードウェア、ソフトウェア、ネットワーク、データベースの大きさ、クエリの内容など、様々な要素をひっくるめた)このシステムのスループットの性能限界は150qpsである」という風に読み取ることができます。 +もしサービスに対するリクエストの件数が増加しつつあり、この限界に近づいているようであれば、クエリの最適化やコンピュータ自体のアップグレードなど、何らかの対策を取ることを検討する必要があると言えます。 + +#### 性能の比較 + +同じリクエストのパターンをGroongaとDroongaに送ることで、各システムの性能を比較することができます。 +もしDroongaの方が性能が良ければ、サービスのバックエンドをGroongaからDroongaに移行する根拠になり得ます。 + +また、異なるノード数での結果を比較すると、新しくノードを追加する際のコストパフォーマンスを分析することもできます。 + + +## ベンチマーク環境を用意する + +新しいDroongaクラスタのために、以下の、互いにホスト名で名前解決できる4つの[Ubuntu][] 14.04LTSのサーバがあると仮定します: + + * `192.168.100.50`、ホスト名:`node0` + * `192.168.100.51`、ホスト名:`node1` + * `192.168.100.52`、ホスト名:`node2` + * `192.168.100.53`、ホスト名:`node3` + +1つはクライアント用で、残りの3つはDroongaノード用です。 + +### 比較対照のデータベース(およびそのデータソース)を用意する + +もしすでにGroongaベースのサービスを運用しているのであれば、それ自体が比較対照となります。 +この場合、Groongaデータベースの内容すべてをダンプ出力し、新しく用意したDroongaクラスタに流し込みさえすれば、性能比較を行えます。 + +特に運用中のサービスが無いということであれば、有効なベンチマークを取るために大量のデータを格納したデータベースを、対照として用意する必要があります。 +[wikipedia-search][]リポジトリには、[Wikipedia日本語版](http://ja.wikipedia.org/)のページを格納したGroongaサーバ(およびDroongaクラスタ)を用意する手助けとなるスクリプトが含まれています。 + +では、Wikipediaのページを格納したGroongaデータベースを、`node0`のノードに準備しましょう。 + + 1. データベースのサイズを決める。 + ベンチマーク測定のためには、十分に大きいサイズのデータベースを使う必要があります。 + + * もしデータベースが小さすぎれば、Droongaのオーバーヘッドが相対的に大きくなるため、Droongaにとって過度に悲観的なベンチマーク結果となるでしょう。 + * もしデータベースが大きすぎれば、メモリのスワップが発生してシステムの性能がランダムに劣化するために、過度に不安定なベンチマーク結果となるでしょう。 + * 各ノードのメモリの搭載量が異なる場合、その中で最もメモリ搭載量が少ないノードに合わせてデータベースのサイズを決めるのが望ましいです。 + + 例えば、`node0` (8GB RAM), `node1` (8GB RAM), `node2` (6GB RAM)の3つのノードがあるとすれば、データベースは6GBよりも小さくするべきです。 + 2. [インストール手順](http://groonga.org/ja/docs/install.html)に従ってGroongaサーバをセットアップする。 + + ~~~ + (on node0) + % sudo apt-get -y install software-properties-common + % sudo add-apt-repository -y universe + % sudo add-apt-repository -y ppa:groonga/ppa + % sudo apt-get update + % sudo apt-get -y install groonga + ~~~ + + これでGroongaを利用できるようになります。. + 3. Rakeのタスク `data:convert:groonga:ja` を使って、Wikipediaのページのアーカイブをダウンロードし、Groongaのダンプファイルに変換する。 + 変換するレコード(ページ)の数は、環境変数 `MAX_N_RECORDS`(初期値は5000)で指定することができます。 + + ~~~ + (on node0) + % cd ~/ + % git clone https://github.com/droonga/wikipedia-search.git + % cd wikipedia-search + % bundle install --path vendor/ + % time (MAX_N_RECORDS=1500000 bundle exec rake data:convert:groonga:ja \ + data/groonga/ja-pages.grn) + ~~~ + + アーカイブは非常に大きいため、ダウンロードと変換には時間がかかります。 + + 変換が終わったら、`~/wikipedia-search/data/groonga/ja-pages.grn`の位置にダンプファイルが生成されています。 + 新しいデータベースを作成し、ダンプファイルの内容を流し込みましょう。 + この操作にも時間がかかります: + + ~~~ + (on node0) + % mkdir -p $HOME/groonga/db/ + % groonga -n $HOME/groonga/db/db quit + % time (cat ~/wikipedia-search/config/groonga/schema.grn | groonga $HOME/groonga/db/db) + % time (cat ~/wikipedia-search/config/groonga/indexes.grn | groonga $HOME/groonga/db/db) + % time (cat ~/wikipedia-search/data/groonga/ja-pages.grn | groonga $HOME/groonga/db/db) + ~~~ + + 注意: レコードの数がデータベースのサイズに影響します。 + 参考までに、検証環境での結果を以下に示します: + + * 30万件のレコードから、1.1GBのデータベースができました。 + データの変換には17分、流し込みには6分を要しました。 + * 150万件のレコードから、4.3GBのデータベースができました。 + データの変換には53分、流し込みには64分を要しました。 + + 4. GroongaをHTTPサーバとして起動する + + ~~~ + (on node0) + % groonga -p 10041 -d --protocol http $HOME/groonga/db/db + ~~~ + +これで、このノードをベンチマーク測定の対照として使う準備が整いました。 + + +### Droongaクラスタをセットアップする + +Droongaをすべてのノードにインストールします。 +HTTP経由での動作をベンチマーク測定するので、`droonga-engine`と`droonga-http-server`の両方をインストールする必要があります。 + +~~~ +(on node0) +% host=node0 +% curl https://raw.githubusercontent.com/droonga/droonga-engine/master/install.sh | \ + sudo HOST=$host bash +% curl https://raw.githubusercontent.com/droonga/droonga-http-server/master/install.sh | \ + sudo ENGINE_HOST=$host HOST=$host PORT=10042 bash +% sudo droonga-engine-catalog-generate \ + --hosts=node0,node1,node2 +% sudo service droonga-engine start +% sudo service droonga-http-server start +~~~ + +~~~ +(on node1) +% host=node1 +... +~~~ + +~~~ +(on node2) +% host=node2 +... +~~~ + +注意: `droonga-http-server`をGroongaとは別のポート番号で起動するために、ここでは`PORT`環境変数を使って上記のようにして`10042`のポートで起動するように指定しています。 + +DroongaのHTTPサーバが動作しており、`10042`番のポートを監視していることと、3つのノードからなるクラスタとして動作していることを確認しておきましょう: + +~~~ +(on node0) +% sudo apt-get install -y jq +% curl "http://node0:10042/droonga/system/status" | jq . +{ + "nodes": { + "node0:10031/droonga": { + "live": true + }, + "node1:10031/droonga": { + "live": true + }, + "node2:10031/droonga": { + "live": true + } + } +} +~~~ + + +### GroongaからDroongaへとデータを同期する + +次に、Droongaのデータベースを用意します。 + +`grn2drn`コマンドを使うと、Groongaのダンプ出力をDroonga用のメッセージに変換することができます。 +コマンドを利用できるようにするために、Groongaサーバとなっているコンピュータに`grn2drn` Gemパッケージをインストールしましょう。 + +~~~ +(on node0) +% sudo gem install grn2drn +~~~ + +また、`rroonga` Gemパッケージの一部として導入される`grndump`コマンドは、既存のGroongaのデータベースからすべてのデータを柔軟に取り出す機能を提供しています。 +もし既存のGroongaサーバからデータを取り出そうとしているのであれば、事前に`rroonga`をインストールしておく必要があります。 + +~~~ +(on Ubuntu server) +% sudo apt-get -y install software-properties-common +% sudo add-apt-repository -y universe +% sudo add-apt-repository -y ppa:groonga/ppa +% sudo apt-get update +% sudo apt-get -y install libgroonga-dev +% sudo gem install rroonga +~~~ + +~~~ +(on CentOS server) +# rpm -ivh http://packages.groonga.org/centos/groonga-release-1.1.0-1.noarch.rpm +# yum -y makecache +# yum -y ruby-devel groonga-devel +# gem install rroonga +~~~ + +それでは、スキーマ定義とデータを別々にダンプ出力し、Droongaクラスタに流し込みましょう。 + +~~~ +(on node0) +% time (grndump --no-dump-tables $HOME/groonga/db/db | \ + grn2drn | \ + droonga-send --server=node0 \ + --report-throughput) +% time (grndump --no-dump-schema --no-dump-indexes $HOME/groonga/db/db | \ + grn2drn | \ + droonga-send --server=node0 \ + --server=node1 \ + --server=node2 \ + --messages-per-second=100 \ + --report-throughput) +~~~ + +スキーマ定義とインデックスの定義については単一のエンドポイントに送るように注意して下さい。 +Droongaは複数のノードに並行してバラバラに送られたスキーマ変更コマンドをソートすることができないので、スキーマ定義のリクエストを複数のエンドポイントに流し込むと、データベースが壊れてしまいます。 + +トラフィックとシステムの負荷を軽減するために、1秒あたりに流入するメッセージの量を`--messages-per-second`オプションで制限するようにしてください。 +大量のメッセージが一度にDroongaクラスタに流れ込むと、システムの限界を超えてしまい、Droongaがメモリを食い潰して、システムを非常に低速にしてしまう恐れがあります。 + +この操作にも時間がかかります。 +例えば `--messages-per-second=100` と指定した場合、150万件のレコードを同期するにはだいたい4時間ほどかかります。(必要な時間は `150000 / 100 / 60 / 60` のような計算式で見積もれます) + +以上の手順により、`10041`ポートを監視するGroonga HTTPサーバと、`10042`ポートを監視するDroonga HTTPサーバの、2つのHTTPサーバを用意できます。 + + +### クライアントをセットアップする + +クライアントにするマシンには、ベンチマーク用のクライアントをインストールする必要があります。 + +`node3`をクライアントとして使うと仮定します: + +~~~ +(on node3) +% sudo apt-get update +% sudo apt-get -y upgrade +% sudo apt-get install -y ruby curl jq +% sudo gem install drnbench +~~~ + + +## リクエストパターンを用意する + +ベンチマーク用のリクエストパターンファイルを用意しましょう。 + +### キャッシュヒット率を決める + +まず、キャッシュヒット率を決める必要があります。 + +もし既に運用中のGroongaベースのサービスがあるのであれば、以下のようにして、`status`コマンドを使ってGroongaデータベースのキャッシュヒット率を調べることができます: + +~~~ +% curl "http://node0:10041/d/status" | jq . +[ + [ + 0, + 1412326645.19701, + 3.76701354980469e-05 + ], + { + "max_command_version": 2, + "alloc_count": 158, + "starttime": 1412326485, + "uptime": 160, + "version": "4.0.6", + "n_queries": 1000, + "cache_hit_rate": 0.5, + "command_version": 1, + "default_command_version": 1 + } +] +~~~ + +キャッシュヒット率は`"cache_hit_rate"`として返却されます。 +`0.5`は50%という意味で、レスポンスのうちの半分がキャッシュされた結果に基づいて返されているということです。 + +運用中のサービスが無いのであれば、ひとまずキャッシュヒット率は50%と過程すると良いでしょう。 + +GroongaとDroongaの性能を正確に比較するためには、キャッシュヒット率が実際の値に近くなるようにリクエストパターンを用意する必要があります。 +さて、どのようにすればよいのでしょうか? + +キャッシュヒット率は、`N = 100 ÷ (キャッシュヒット率)`という式で計算した、ユニーク(一意)なリクエストパターンの数で制御できます。 +これは、GroongaとDroonga(`droonga-http-server`)が既定の状態で最大で100件までの結果をキャッシュするためです。 +期待されるキャッシュヒット率が50%なのであれば、用意するべきユニークなリクエストの数は`N = 100 ÷ 0.5 = 200`と計算できます。 + +注意: 実際のキャッシュヒット率が0に近い場合、必要となるユニークなリクエストの件数が巨大になってしまいます。 +このような場合は、キャッシュヒット率を`0.01`(1%)程度と見なすとよいでしょう。 + + +### リクエストパターンファイルの書式 + +`drnbench-request-response`用のリクエストパターンのリストは、HTTPリクエストのパスのリストであるプレーンテキスト形式で作成します。 +以下はGroongaの`select`コマンド用のリクエストの一覧の例です: + +~~~ +/d/select?command_version=2&table=Pages&limit=10&match_columns=title&output_columns=title&query=AAA +/d/select?command_version=2&table=Pages&limit=10&match_columns=title&output_columns=title&query=BBB +... +~~~ + +もし既存のGroongaベースのサービスを運用しているのであれば、リクエストパターンのリストは、実際のアクセスログやクエリログなどから生成するのが望ましいです。 +実際のリクエストに近いパターンであるほど、システムの性能をより有効に測定できます。 +ユニークなリクエストパターンを200件作るには、ログからユニークなリクエスト先パスを200件収集してくればOKです。 + +運用中のサービスが無い場合は、何らかの方法でリクエストパスのリストを作る必要があります。 +詳しくは事項を参照して下さい。 + +### 検索語句のリストを用意する + +200件のユニークなリクエストパターンを作るには、200個の語句を用意する必要があります。 +しかも、それらはすべて実際にGroongaのデータベースで有効な検索結果を返すものでなくてはなりません。 +もしランダムに生成した単語(例えば`P2qyNJ9L`, `Hy4pLKc5`, `D5eftuTp`……といった具合)を使った場合、ほとんどのリクエストに対して「ヒット無し」という検索結果が返されてしまうため、有効なベンチマーク結果を得ることができません。 + +こんな時のために、`drnbench-extract-searchterms`というユーティリティコマンドがあります。 +これは、以下のようにしてGroongaの検索結果から単語のリストを生成します: + +~~~ +% curl "http://node0:10041/d/select?command_version=2&table=Pages&limit=10&output_columns=title" | \ + drnbench-extract-searchterms +title1 +title2 +title3 +... +title10 +~~~ + +`drnbench-extract-searchterms`は検索結果のレコードの最初の列の値を単語として取り出します。 +200件の有効な検索語句を得るには、単に`limit=200`と指定して検索結果を得ればOKです。 + + +### 与えられた語句からリクエストパターンファイルを生成する + +では、`drnbench-extract-searchterms`を使って、Groongaの検索結果からリクエストパターンを生成してみましょう。 + +~~~ +% n_unique_requests=200 +% curl "http://node0:10041/d/select?command_version=2&table=Pages&limit=$n_unique_requests&output_columns=title" | \ + drnbench-extract-searchterms --escape | \ + sed -r -e "s;^;/d/select?command_version=2\&table=Pages\&limit=10\&match_columns=title,text\&output_columns=snippet_html(title),snippet_html(text),categories,_key\&query_flags=NONE\&sortby=title\&drilldown=categories\&drilldown_limit=10\&drilldown_output_columns=_id,_key,_nsubrecs\&drilldown_sortby=_nsubrecs\&query=;" \ + > ./patterns.txt +~~~ + +注意: + + * sedスクリプトの中の`&`は、前にバックスラッシュを置いて`\&`のようにエスケープする必要があることに注意して下さい。 + * `drnbench-extract-searchterms`コマンドには、`--escape`オプションを指定すると良いでしょう。 + この指定により、URIに含められない文字がエスケープされます。 + * 得られた検索語句を`query`パラメータに使用する場合、`query_flags=NONE`も同時に指定すると良いでしょう。 + この指定により、Groongaは`query`パラメータの中に含まれる特殊文字を無視するようになります。 + この指定を忘れると、不正なクエリのエラーに遭遇することになるかもしれません。 + +生成されたファイル `patterns.txt` は以下のような内容になります: + +~~~ +/d/select?command_version=2&table=Pages&limit=10&match_columns=title,text&output_columns=snippet_html(title),snippet_html(text),categories,_key&query_flags=NONE&sortby=title&drilldown=categories&drilldown_limit=10&drilldown_output_columns=_id,_key,_nsubrecs&drilldown_sortby=_nsubrecs&query=AAA +/d/select?command_version=2&table=Pages&limit=10&match_columns=title,text&output_columns=snippet_html(title),snippet_html(text),categories,_key&query_flags=NONE&sortby=title&drilldown=categories&drilldown_limit=10&drilldown_output_columns=_id,_key,_nsubrecs&drilldown_sortby=_nsubrecs&query=BBB +... +~~~ + + +## ベンチマークを実行する + +以上で、準備が整いました。 +それではGroongaとDroongaのベンチマークを取得してみましょう。 + +### Groongaのベンチマークを行う + +まず、比較対照としてGroongaでのベンチマーク結果を取得します。 +`node0`を比較対照用のGroongaサーバとしてセットアップ済みで、GroongaのHTTPサーバが停止している場合には、ベンチマークの実行前にあらかじめ起動しておいて下さい。 + +~~~ +(on node0) +% groonga -p 10041 -d --protocol http $HOME/groonga/db/db +~~~ + +ベンチマークは以下の要領で、`drnbench-request-response`コマンドを実行すると測定できます: + +~~~ +(on node3) +% drnbench-request-response \ + --step=2 \ + --start-n-clients=0 \ + --end-n-clients=20 \ + --duration=30 \ + --interval=10 \ + --request-patterns-file=$PWD/patterns.txt \ + --default-hosts=node0 \ + --default-port=10041 \ + --output-path=$PWD/groonga-result.csv +~~~ + +重要なパラメータは以下の通りです: + + * `--step` は、各段階で増やす仮想クライアントの数です。 + * `--start-n-clients` は、仮想クライアントの最初の数です。 + 例え`0`を指定したとしても、最初の実行時には必ず1つはクライアントが生成されます。 + * `--end-n-clients` は、仮想クライアントの最大数です。 + ベンチマークは、クライアントの数がこの上限に達するまでの間繰り返し実行されます。 + * `--duration` は、1回あたりのベンチマークの実行にかける時間です。 + この値は、結果が安定するまでに十分な長さの時間を指定するのが望ましいです。 + 筆者の場合は`30`(秒)が最適でした。 + * `--interval` は、ベンチマークの合間に設ける待ち時間です。 + これは、前回のベンチマークが終了するのに十分な長さの時間を指定するのが望ましいです。 + 筆者の場合は`10`(秒)が最適でした。 + * `--request-patterns-file` は、パターンファイルへのパスです。 + * `--default-hosts` は、リクエストの送信先のホスト名の一覧です。 + 複数のホストをカンマで区切って指定すると、ロードバランサーの動作をシミュレートすることもできます。 + * `--default-port` は、リクエストの送信先のポート番号です。 + * `--output-path` は、結果の出力先ファイルへのパスです。 + すべてのベンチマークの統計情報が、この位置にファイルとして保存されます。 + +ベンチマークの実行中は、`node0`のシステムの状態を`top`コマンドなどを使って監視しておきましょう。 +もしベンチマークがGroongaの性能を正しく引き出していれば、GroongaのプロセスはCPUをフルに使い切っているはずです(プロセッサ数4ならば`400%`、といった具合に)。 +そうでない場合は、何かがおかしいです。例えばネットワーク帯域が細すぎるのかもしれませんし、クライアントが非力すぎるのかもしれません。 + +これで、対照用のGroongaでの結果を得る事ができます。 + +結果が妥当かどうかを確かめるために、`status`コマンドの結果を確認しましょう: + +~~~ +% curl "http://node0:10041/d/status" | jq . +[ + [ + 0, + 1412326645.19701, + 3.76701354980469e-05 + ], + { + "max_command_version": 2, + "alloc_count": 158, + "starttime": 1412326485, + "uptime": 160, + "version": "4.0.6", + "n_queries": 1000, + "cache_hit_rate": 0.49, + "command_version": 1, + "default_command_version": 1 + } +] +~~~ + +`"cache_hit_rate"`の値に注目してください。 +この値が想定されるキャッシュ率(例えば`0.5`)からかけ離れている場合、何かがおかしいです。例えば、リクエストパターンの数が少なすぎるかも知れません。 +キャッシュヒット率が高すぎる場合、結果のスループットは本来よりも高すぎる値になってしまいます。 + +Droongaノードの上でGroongaを動かしている場合は、CPU資源とメモリ資源を解放するために、ベンチマーク取得後はGroongaを停止しておきましょう。 + +~~~ +(on node0) +% pkill groonga +~~~ + +### Droongaのベンチマークを行う + +#### 1ノード構成でのDroongaのベンチマーク + +ベンチマークの前に、ノードが1つだけの状態にクラスタを設定します。 + +~~~ +(on node1, node2) +% sudo service droonga-engine stop +% sudo service droonga-http-server stop +~~~ + +~~~ +(on node0) +% sudo droonga-engine-catalog-generate \ + --hosts=node0 +% sudo service droonga-engine restart +% sudo service droonga-http-server restart +~~~ + +前回のベンチマークの影響をなくすために、各ベンチマークの実行前にはサービスを再起動することをおすすめします。 + + +これにより、`node0`は1ノード構成のクラスタとして動作するようになります。 +実際にノードが1つだけ認識されていることを確認しましょう: + +~~~ +(on node3) +% curl "http://node0:10042/droonga/system/status" | jq . +{ + "nodes": { + "node0:10031/droonga": { + "live": true + } + } +} +~~~ + +ベンチマークを実行しましょう。 + +~~~ +(on node3) +% drnbench-request-response \ + --step=2 \ + --start-n-clients=0 \ + --end-n-clients=20 \ + --duration=30 \ + --interval=10 \ + --request-patterns-file=$PWD/patterns.txt \ + --default-hosts=node0 \ + --default-port=10042 \ + --output-path=$PWD/droonga-result-1node.csv +~~~ + +デフォルトのポートが`10041`(GroongaのHTTPサーバのポート)から`10042`(Droongaのポート)に変わっていることに注意して下さい。 +結果の保存先のパスも変わっています。 + +ベンチマークの実行中、`node0`のシステムの状態を`top`コマンドなどで監視しておきましょう。 +これはボトルネックの分析に役立ちます。 + +また、結果が正しいかどうかを確かめるために、実際のキャッシュヒット率を確認しておきましょう: + +~~~ +% curl "http://node0:10042/statistics/cache" | jq . +{ + "hitRatio": 49.830717830807124, + "nHits": 66968, + "nGets": 134391 +} +~~~ + +`"hitRatio"`の値に注目してください。HTTPサーバにおける実際のキャッシュヒット率は、上記のようにパーセンテージで示されます(`49.830717830807124`という値はそのまま`49.830717830807124%`ということです)。 +もし値が期待されるキャッシュヒット率と大きく異なっている場合、何かがおかしいです。 + +#### 2ノード構成でのDroongaのベンチマーク + +ベンチマークの前に、2番目のノードをクラスタに参加させます。 + +~~~ +(on node0, node1) +% sudo droonga-engine-catalog-generate \ + --hosts=node0,node1 +% sudo service droonga-engine restart +% sudo service droonga-http-server restart +~~~ + +これにより、`node0`と`node1`は2ノード構成のDroongaクラスタとして動作するようになります。 +実際にノードが2つ認識されていることを確認しましょう: + +~~~ +(on node3) +% curl "http://node0:10042/droonga/system/status" | jq . +{ + "nodes": { + "node0:10031/droonga": { + "live": true + }, + "node1:10031/droonga": { + "live": true + } + } +} +~~~ + +ベンチマークを実行しましょう。 + +~~~ +(on node3) +% drnbench-request-response \ + --step=2 \ + --start-n-clients=0 \ + --end-n-clients=20 \ + --duration=30 \ + --interval=10 \ + --request-patterns-file=$PWD/patterns.txt \ + --default-hosts=node0,node1 \ + --default-port=10042 \ + --output-path=$PWD/droonga-result-2nodes.csv +~~~ + +`--default-hosts` で2つのホストを指定していることに注意して下さい。 + +今の所、`droonga-http-server`はシングルプロセスのため、すべてのリクエストを1つだけのホストに送ると`droonga-http-server`がボトルネックとなってしまいます。 +また、`droonga-http-server`と`droonga-engine`がCPU資源を奪い合うことにもなります。 +Droongaクラスタの性能を有効に測定するためには、各ノードのCPU使用率を平滑化する必要があります。 + +もちろん、実際のプロダクション環境ではこのようなリクエストの分配はロードバランサーによって行われるべきですが、ベンチマークのためだけにロードバランサーを設定するのは煩雑です。 +`--default-hosts`オプションにカンマ区切りで複数のホスト名を指定することで、その代替とすることができます。 + +また、結果の保存先のパスも変えています。 + +ベンチマークの実行中、両方のノードのシステムの状態を監視することを忘れないでください。 +もし片方のノードだけに負荷がかかっていてもう片方がアイドル状態なのであれば、両者が1つのクラスタとして働いていないなどのように、何か異常が起こっていると分かります。 +すべてのノードの実際のキャッシュヒット率も忘れずに確認しておきましょう。 + +#### 3ノード構成でのDroongaのベンチマーク + +ベンチマークの前に、最後のノードをクラスタに参加させましょう。 + +~~~ +(on node0, node1) +% sudo droonga-engine-catalog-generate \ + --hosts=node0,node1,node2 +% sudo service droonga-engine restart +% sudo service droonga-http-server restart +~~~ + +これで、`node0`, `node1`, `node2`のすべてのノードが3ノード構成のクラスタとして動作するようになります。 +実際にノードが3つ認識されていることを確認しましょう: + +~~~ +(on node3) +% curl "http://node0:10042/droonga/system/status" | jq . +{ + "nodes": { + "node0:10031/droonga": { + "live": true + }, + "node1:10031/droonga": { + "live": true + }, + "node2:10031/droonga": { + "live": true + } + } +} +~~~ + +ベンチマークを実行しましょう。 + +~~~ +(on node3) +% drnbench-request-response \ + --step=2 \ + --start-n-clients=0 \ + --end-n-clients=20 \ + --duration=30 \ + --interval=10 \ + --request-patterns-file=$PWD/patterns.txt \ + --default-hosts=node0,node1,node2 \ + --default-port=10042 \ + --output-path=$PWD/droonga-result-3nodes.csv +~~~ + +また`--default-hosts`と`--output-path`の指定も変えていることに注意して下さい。 +各ノードのシステムの状態の監視と、実際のキャッシュヒット率の確認も忘れてはいけません。 + +## 結果を分析する + +これで、手元に4つの結果が集まりました: + + * `groonga-result.csv` + * `droonga-result-1node.csv` + * `droonga-result-2nodes.csv` + * `droonga-result-3nodes.csv` + +[先に述べた通り](#how-to-analyze)、これらを使って傾向を分析することができます。 + +例えば、これらの結果は以下のようにグラフ化できます: + + + +このレイテンシーのグラフは以下のように読み取れます: + + * Droongaのレイテンシーの下限はGroongaのそれよりも大きい。 + Droongaにはオーバーヘッドがある。 + * 複数ノードのDroongaのレイテンシーはGroongaに比べると緩やかに増大している。 + Droongaは余計な待ち時間無しでより多くのリクエストを同時に処理できる。 + + + +このスループットのグラフは以下のように読み取れます: + + * GroongaのグラフとDroongaの単一ノード時のグラフは似通っている。 + GroongaとDroongaの間での性能の劣化はごくわずかである。 + * Droongaのスループット性能はノード数によって増大する。 + +(注意: 性能測定の結果は様々な要因によって変動します。 +これはあくまで特定のバージョン、特定の環境での結果の例です。) + +## まとめ + +このチュートリアルでは、比較対照としての[Groonga][]サーバと、[Droonga]クラスタを用意しました。 +また、リクエストパターンを用意する手順、システムの性能の測定方法、結果の分析方法なども学びました。 + + [Ubuntu]: http://www.ubuntu.com/ + [CentOS]: https://www.centos.org/ + [Droonga]: https://droonga.org/ + [Groonga]: http://groonga.org/ + [drnbench]: https://github.com/droonga/drnbench/ + [wikipedia-search]: https://github.com/droonga/wikipedia-search/ + [command reference]: ../../reference/commands/ Added: ja/tutorial/1.1.2/dump-restore/index.md (+616 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/dump-restore/index.md 2015-11-15 23:29:56 +0900 (13be2fc) @@ -0,0 +1,616 @@ +--- +title: "Droongaチュートリアル: データベースのバックアップと復元" +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/dump-restore/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## チュートリアルのゴール + +データのバックアップと復元を手動で行う際の手順を学ぶこと。 + +## 前提条件 + +* 何らかのデータが格納されている状態の[Droonga][]クラスタがあること。 + このチュートリアルを始める前に、[「使ってみる」のチュートリアル](../groonga/)を完了しておいて下さい。 + +このチュートリアルでは、[1つ前のチュートリアル](../groonga/)で準備した2つの既存のDroongaノード:`node0` (`192.168.100.50`) 、 `node1` (`192.168.100.51`) と、作業環境として使うもう1台のコンピュータ `node2` (`192.168.100.52`) があると仮定します。 +あなたの手元にあるDroongaノードがこれとは異なる名前である場合には、以下の説明の中の`node0`、`node1`、`node2`は実際の物に読み替えて下さい。 + +## Droongaクラスタのデータをバックアップする + +### `drndump` のインストール + +最初に、作業マシンの`node2`にRubygems経由で `drndump` と名付けられたコマンドラインツールをインストールします: + +~~~ +# gem install drndump +~~~ + +その後、[`drndump`コマンド][drndump-command]が正しくインストールできたかどうかを確認します: + +~~~ +$ drndump --version +drndump 1.0.1 +~~~ + +### Droongaクラスタ内のデータをダンプする + +`drndump` コマンドはすべてのスキ−マ定義とデータをJSONs形式で取り出します。既存のDroongaクラスタのすべての内容をダンプ出力してみましょう。 + +例えば、クラスタが `node0` (`192.168.100.50`) と `node1` (`192.168.100.51`) の2つのノードから構成されていて、別のホスト `node2` (`192.168.100.52`) にログインしている場合、コマンドラインは以下の要領です。 + +~~~ +# drndump --host=node0 \ + --receiver-host=node2 +{ + "type": "table_create", + "dataset": "Default", + "body": { + "name": "Location", + "flags": "TABLE_PAT_KEY", + "key_type": "WGS84GeoPoint" + } +} +... +{ + "dataset": "Default", + "body": { + "table": "Store", + "key": "store9", + "values": { + "location": "146702531x-266363233", + "name": "Macy's 6th Floor - Herald Square - New York NY (W)" + } + }, + "type": "add" +} +{ + "type": "column_create", + "dataset": "Default", + "body": { + "table": "Location", + "name": "store", + "type": "Store", + "flags": "COLUMN_INDEX", + "source": "location" + } +} +{ + "type": "column_create", + "dataset": "Default", + "body": { + "table": "Term", + "name": "store_name", + "type": "Store", + "flags": "COLUMN_INDEX|WITH_POSITION", + "source": "name" + } +} +~~~ + +以下の点に注意して下さい: + + * `--host` オプションには、クラスタ内のいずれかのノードの正しいホスト名またはIPアドレスを指定します。 + * `--receiver-host` オプションには、今操作しているコンピュータ自身の正しいホスト名またはIPアドレスを指定します。 + この情報は、Droongaクラスタがメッセージを送り返すために使われます。 + * コマンドの実行結果は、ダンプ出力元と同じ内容のデータセットを構築するのに必要なすべての情報を含んでいます。 + +実行結果は標準出力に出力されます。 +結果をJSONs形式のファイルに保存する場合は、リダイレクトを使って以下のようにして下さい: + +~~~ +$ drndump --host=node0 \ + --receiver-host=node2 \ + > dump.jsons +~~~ + + +## Droongaクラスタのデータを復元する + +### `droonga-client`のインストール + +[`drndump`コマンド][drndump-command]の実行結果は、Droonga用のメッセージの一覧です。 + +Droongaクラスタにそれらのメッセージを送信するには、[`droonga-send`コマンド][droonga-send-command]を使います。 +このコマンドを含んでいるGemパッケージ `droonga-client` を、作業マシンである`node2`にインストールして下さい: + +~~~ +# gem install droonga-client +~~~ + +[`droonga-send`コマンド][droonga-send-command]が正しくインストールされた事を確認しましょう: + +~~~ +$ droonga-send --version +droonga-send 0.2.1 +~~~ + +### 空のDroongaクラスタを用意する + +2つのノード `node0` (`192.168.100.50`) と `node1` (`192.168.100.51`) からなる空のクラスタがあり、今 `node2` (`192.168.100.52`) にログインして操作を行っていて、ダンプファイルが `dump.jsons` という名前で手元にあると仮定します。 + +もし順番にこのチュートリアルを読み進めているのであれば、クラスタとダンプファイルが既に手元にあるはずです。以下の操作でクラスタを空にしましょう: + +~~~ +$ endpoint="http://node0:10041" +$ curl "$endpoint/d/table_remove?name=Location" | jq "." +[ + [ + 0, + 1406610703.2229023, + 0.0010793209075927734 + ], + true +] +$ curl "$endpoint/d/table_remove?name=Store" | jq "." +[ + [ + 0, + 1406610708.2757723, + 0.006396293640136719 + ], + true +] +$ curl "$endpoint/d/table_remove?name=Term" | jq "." +[ + [ + 0, + 1406610712.379644, + 6.723403930664062e-05 + ], + true +] +~~~ + +これでクラスタは空になりました。 +確かめてみましょう。 +以下のように、`select`と`table_list`コマンドは空の結果を返します: + +~~~ +$ curl "$endpoint/d/table_list" | jq "." +[ + [ + 0, + 1406610804.1535122, + 0.0002875328063964844 + ], + [ + [ + [ + "id", + "UInt32" + ], + [ + "name", + "ShortText" + ], + [ + "path", + "ShortText" + ], + [ + "flags", + "ShortText" + ], + [ + "domain", + "ShortText" + ], + [ + "range", + "ShortText" + ], + [ + "default_tokenizer", + "ShortText" + ], + [ + "normalizer", + "ShortText" + ] + ] + ] +] +$ curl -X DELETE "$endpoint/cache" | jq "." +true +$ curl "$endpoint/d/select?table=Store&output_columns=name&limit=10" | jq "." +[ + [ + 0, + 1401363465.610241, + 0 + ], + [ + [ + [ + null + ], + [] + ] + ] +] +~~~ + +`select`コマンドにクエストを送る前に、まずキャッシュを削除しておくことに注意して下さい。 +これを忘れると、古い情報に基づいて、キャッシュされた結果が意図せず返されてしまいます。 + +既定の設定では、レスポンスキャッシュは直近の100リクエストに対して保存され、保持期間は1分間です。 +上記のように、`/cache`のパスの位置にHTTPの`DELETE`のリクエストを送信すると、手動でレスポンスキャッシュを削除できます。 + +### ダンプ結果から空のDroongaクラスタへデータを復元する + +[`drndump`コマンド][drndump-command]の実行結果はダンプ出力元と同じ内容のデータセットを作るために必要な情報をすべて含んでいます。そのため、クラスタが壊れた場合でも、ダンプファイルからクラスタを再構築する事ができます。 +やり方は単純で、単にダンプファイルを[`droonga-send`コマンド][droonga-send-command]を使って空のクラスタに流し込むだけです。 + +ダンプファイルからクラスタの内容を復元するには、以下のようなコマンドを実行します: + +~~~ +$ droonga-send --server=node0 \ + dump.jsons +~~~ + +注意: + + * `--server` オプションには、クラスタ内のいずれかのノードの正しいホスト名またはIPアドレスを指定します。 + +これで、データが完全に復元されました。確かめてみましょう: + +~~~ +$ curl -X DELETE "$endpoint/cache" | jq "." +true +$ curl "$endpoint/d/select?table=Store&output_columns=name&limit=10" | jq "." +[ + [ + 0, + 1401363556.0294158, + 7.62939453125e-05 + ], + [ + [ + [ + 40 + ], + [ + [ + "name", + "ShortText" + ] + ], + [ + "1st Avenue & 75th St. - New York NY (W)" + ], + [ + "76th & Second - New York NY (W)" + ], + [ + "Herald Square- Macy's - New York NY" + ], + [ + "Macy's 5th Floor - Herald Square - New York NY (W)" + ], + [ + "80th & York - New York NY (W)" + ], + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "45th & Broadway - New York NY (W)" + ], + [ + "Marriott Marquis - Lobby - New York NY" + ], + [ + "Second @ 81st - New York NY (W)" + ], + [ + "52nd & Seventh - New York NY (W)" + ] + ] + ] +] +~~~ + +## 既存のクラスタを別の空のクラスタに直接複製する + +複数のDroongaクラスタが存在する場合、片方のクラスタの内容をもう片方のクラスタに複製することができます。 +`droonga-engine` パッケージは[`droonga-engine-absorb-data`というユーティリティコマンド][droonga-engine-absorb-data-command]を含んでおり、これを使うと、既存のクラスタから別のクラスタへ直接データをコピーする事ができます。ローカルにダンプファイルを保存する必要がない場合には、この方法がおすすめです。 + +### 複数のDroongaクラスタを用意する + +ノード `node0` (`192.168.100.50`) を含む複製元クラスタと、ノード `node1' (`192.168.100.51`) を含む複製先クラスタの2つのクラスタがあると仮定します。 + +もし順番にこのチュートリアルを読み進めているのであれば、2つのノードを含むクラスタが手元にあるはずです。[`droonga-engine-catalog-modify`][droonga-engine-catalog-modify-command]を使って2つのクラスタを作り、1つを空にしましょう。手順は以下の通りです: + +~~~ +(on node0) +# droonga-engine-catalog-modify --replica-hosts=node0 +~~~ + +~~~ +(on node1) +# droonga-engine-catalog-modify --replica-hosts=node1 +~~~ + +これらのコマンドによって、2ノードからなる1つのクラスタが、それぞれ1ノードからなる2つのクラスタへ分割されます。 +カタログ定義ファイルの変更は`droonga-engine`サービスによって自動的に検出され、プロセスが自動的に再起動されます。 + +この処理には時間がかかるため、完了まで1分程度待つ必要があります。 +もしそのノード上で動作中の`droonga-engine-service`のプロセスが2つ以上あるのであれば、そのノードはまだ再起動処理の途中です。 +(新しいサービスのプロセスが動作し始めたら、古いプロセスが自動的に終了します。) + +~~~ +(on node0, node1) +$ ps aux | grep droonga-engine-service | grep -v grep | wc -l +2 +~~~ + +しばらく待つと、各ノード上でサービスのプロセスが1つだけ動作している状態になります: + +~~~ +(on node0, node1) +$ ps aux | grep droonga-engine-service | grep -v grep | wc -l +1 +~~~ + +これで、2つの別々のクラスタができました: + +~~~ +$ curl "http://node0:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node0:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +$ curl "http://node1:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +~~~ + +では、片方のクラスタを空にしましょう: + +~~~ +(on node1) +$ endpoint="http://node1:10041" +$ curl "$endpoint/d/table_remove?name=Location" +$ curl "$endpoint/d/table_remove?name=Store" +$ curl "$endpoint/d/table_remove?name=Term" +$ curl -X DELETE "http://node1:10041/cache" | jq "." +true +$ curl "http://node1:10041/d/select?table=Store&output_columns=name&limit=10" | jq "." +[ + [ + 0, + 1401363465.610241, + 0 + ], + [ + [ + [ + null + ], + [] + ] + ] +] +$ curl -X DELETE "http://node0:10041/cache" | jq "." +true +$ curl "http://node0:10041/d/select?table=Store&output_columns=name&limit=10" | jq "." +[ + [ + 0, + 1401363556.0294158, + 7.62939453125e-05 + ], + [ + [ + [ + 40 + ], + [ + [ + "name", + "ShortText" + ] + ], + [ + "1st Avenue & 75th St. - New York NY (W)" + ], + [ + "76th & Second - New York NY (W)" + ], + [ + "Herald Square- Macy's - New York NY" + ], + [ + "Macy's 5th Floor - Herald Square - New York NY (W)" + ], + [ + "80th & York - New York NY (W)" + ], + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "45th & Broadway - New York NY (W)" + ], + [ + "Marriott Marquis - Lobby - New York NY" + ], + [ + "Second @ 81st - New York NY (W)" + ], + [ + "52nd & Seventh - New York NY (W)" + ] + ] + ] +] +~~~ + +`droonga-http-server`は同じコンピュータ上の`droonga-engine`に関連付けられていることに注意してください。 +上記の手順でクラスタを2つに分割した後は、`node0`の`droonga-http-server`は`node0`の`droonga-engine`とだけ通信し、`node1`の`droonga-http-server`は`node1`の`droonga-engine`とだけ通信します。 +詳しくは次のチュートリアルも参照して下さい。 + + +### 2つのDroongaクラスタの間でデータを複製する + +2つのクラスタの間でデータをコピーするには、いずれかのノード上で以下のように[`droonga-engine-absorb-data`コマンド][droonga-engine-absorb-data-command]を実行します: + +~~~ +(on node1) +$ droonga-engine-absorb-data --host=node1 \ + --source-host=node0 \ + --receiver-host=node1 +Start to absorb data from Default at node0:10031/droonga + to Default at node1:10031/droonga + via node1 (this host) + +Absorbing... +Getting the timestamp of the last processed message in the source node... +The timestamp of the last processed message in the source node: 2015-04-29T10:07:08.230158Z +Setting the destination node to ignore messages older than the timestamp... +100% done (maybe 00:00:00 remaining) +Done. +~~~ + +このコマンドは、以下のようにして別のノード上で実行することもできます: + +~~~ +(on node2) +$ droonga-engine-absorb-data --host=node1 \ + --source-host=node0 \ + --receiver-host=node2 +Start to absorb data from Default at node0:10031/droonga + to Default at node1:10031/droonga + via node2 (this host) +... +~~~ + +この時、コマンドを実行するノードのホスト名かIPアドレスを`--receiver-host`オプションで指定する必要があることに注意してください。 + +以上の操作で、2つのクラスタの内容が完全に同期されました。確かめてみましょう: + +~~~ +$ curl -X DELETE "http://node1:10041/cache" | jq "." +true +$ curl "http://node1:10041/d/select?table=Store&output_columns=name&limit=10" | jq "." +[ + [ + 0, + 1401363556.0294158, + 7.62939453125e-05 + ], + [ + [ + [ + 40 + ], + [ + [ + "name", + "ShortText" + ] + ], + [ + "1st Avenue & 75th St. - New York NY (W)" + ], + [ + "76th & Second - New York NY (W)" + ], + [ + "Herald Square- Macy's - New York NY" + ], + [ + "Macy's 5th Floor - Herald Square - New York NY (W)" + ], + [ + "80th & York - New York NY (W)" + ], + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "45th & Broadway - New York NY (W)" + ], + [ + "Marriott Marquis - Lobby - New York NY" + ], + [ + "Second @ 81st - New York NY (W)" + ], + [ + "52nd & Seventh - New York NY (W)" + ] + ] + ] +] +~~~ + +### 2つのDroongaクラスタを結合する + +これらの2つのクラスタを結合するために、以下のコマンド列を実行しましょう: + +~~~ +(on node0) +# droonga-engine-catalog-modify --add-replica-hosts=node1 +~~~ + +~~~ +(on node1) +# droonga-engine-catalog-modify --add-replica-hosts=node0 +~~~ + +これで、1つだけクラスタがある状態になりました。最初の状態に戻ったという事になります。 +(もちろん、サービスが完全に再起動されるまでしばらく待つ必要があります。) + +~~~ +$ curl "http://node0:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +~~~ + +## まとめ + +このチュートリアルでは、[Droonga][]クラスタのバックアップとデータの復元の方法を実践しました。 +また、既存のDroongaクラスタの内容を別の空のクラスタへ複製する方法も実践しました。 + +続いて、[既存のDroongaクラスタに新しいreplicaを追加する手順](../add-replica/)を学びましょう。 + + [Ubuntu]: http://http://ubuntulinux.jp/ + [Droonga]: https://droonga.org/ja/ + [Groonga]: http://groonga.org/ja/ + [command reference]: /ja/reference/commands/ + [drndump-command]: /ja/reference/command-line-tools/drndump/ + [droonga-send-command]: /ja/reference/command-line-tools/droonga-send/ + [droonga-engine-absorb-data-command]: /ja/reference/command-line-tools/droonga-engine-absorb-data/ + [droonga-engine-catalog-modify-command]: /ja/reference/command-line-tools/droonga-engine-catalog-modify/ Added: ja/tutorial/1.1.2/groonga/index.md (+1028 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/groonga/index.md 2015-11-15 23:29:56 +0900 (c947bd6) @@ -0,0 +1,1028 @@ +--- +title: "Droongaチュートリアル: 使ってみる/Groongaからの移行手順" +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/groonga/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## チュートリアルのゴール + +Droongaクラスタを自分で構築して、[Groonga][groonga]互換のサーバとして利用できるようにするための手順を学ぶこと。 + +## 前提条件 + +* [Ubuntu][]または[CentOS][]サーバのセットアップと操作について、基本的な知識と経験があること。 +* [Groonga][groonga]のHTTP経由での利用について、基本的な知識と経験があること。 + +## Droongaとは何か? + +Droongaは分散アーキテクチャに基づくデータ処理エンジンで、「distributed-Groonga」がその名の由来です。 +名前が示す通り、Droongaはいくつかの点での改善(具体的には、レプリケーションとシャーディング)を含んだGroonga互換のサーバとして動作することができます。 + +アーキテクチャ、設計、APIなどの点で、DroongaはGroongaと大きく異なっています。 +しかしながら、Droongaを単にGroonga互換のサーバとして使う限りにおいては、Droongaのアーキテクチャ全体を理解する必要はありません。 + +例として、[ニューヨークにあるスターバックスの店舗](http://geocommons.com/overlays/430038)を検索できるデータベースシステムを作成することにします。 + +## Droongaクラスタをセットアップする + +Droongaベースのデータベースシステムは、*Droongaクラスタ*と呼ばれます。 +この節では、Droongaクラスタを0から構築する方法を解説します。 + +### Droongaノード用のコンピュータを用意する + +Droongaクラスタは、*Droongaノード*と呼ばれる1つ以上のコンピュータによって構成されます。 +まず、Droongaノードにするためのコンピュータを用意しましょう。 + +このチュートリアルは、既存のコンピュータを使ってDroongaクラスタを構築する手順について解説しています。 +以下の説明は基本的には、[DigitalOcean](https://www.digitalocean.com/)上のサーバで`Ubuntu 14.04 x64`または`CentOS 7 x64`の仮想マシンが正しく準備されており、コンソールが利用できる状態になっている、という前提に基づいています。 + +単にDroongaを試したいだけの場合は、[自分のコンピュータ上に複数台の仮想マシンを用意する手順の解説](../virtual-machines-for-experiments/)も参照してみて下さい。 + +注意: + + * Droongaの依存パッケージをインストールする前に、仮想マシンのインスタンスが少なくとも2GB以上のメモリを備えていることを確認して下さい。 + メモリが足りないと、パッケージのインストール中にネイティブ拡張のビルドに失敗する場合があります。 + * `hostname -f`で報告されるホスト名、または`hostname -i`で報告されるIPアドレスが、クラスタ内の他のコンピュータからアクセス可能なものであることを確認して下さい。 + * `curl`コマンドと`jq`コマンドがインストールされていることを確認して下さい。 + `curl`はインストールスクリプトをダウンロードするために必要です。 + `jq`はインストールのためには必要ではありませんが、Droongaが返却するJSON形式のレスポンスを読むのに役立つでしょう。 + +有効なレプリケーションを実現するためには2台以上のコンピュータを用意する必要があります。 +ですので、このチュートリアルでは以下のような2台のコンピュータがあると仮定して説明を進めます: + + * IPアドレスが`192.168.100.50`で、ホスト名が`node0`であるコンピュータ。 + * IPアドレスが`192.168.100.51`で、ホスト名が`node1`であるコンピュータ。 + +## コンピュータをDroongaノードとしてセットアップする + +Groongaはバイナリのパッケージを提供しているため、環境によっては簡単にインストールできます。 +([Groongaのインストール手順](http://groonga.org/docs/install.html)を参照) + +それに対し、コンピュータをDroongaノードとしてセットアップする手順は以下の通りです: + + 1. `droonga-engine`をインストールする。 + 2. `droonga-http-server`をインストールする。 + 3. そのノードを他のノードと協調して動作するように設定する。 + +上記の手順を各コンピュータに対して実施する必要があることに注意して下さい。 +しかしながら、各手順は非常に簡単です。 + +それでは、`node0` (`192.168.100.50`)にログインしてDroongaの構成コンポーネントをインストールしましょう。 + +まず、`droonga-engine`をインストールします。 +これはDroongaシステムの主要な機能を提供する、核となるコンポーネントです。 +インストールスクリプトをダウンロードし、root権限で`bash`で実行して下さい: + +~~~ +# curl https://raw.githubusercontent.com/droonga/droonga-engine/master/install.sh | \ + bash +... +Installing droonga-engine from RubyGems... +... +Preparing the user... +... +Setting up the configuration directory... +This node is configured with a hostname XXXXXXXX. + +Registering droonga-engine as a service... +... +Successfully installed droonga-engine. +~~~ + +そのノード自身の名前(コンピュータのホスト名から推測されたもの)がメッセージの中に出力されていることに注意して下さい。 +*この名前は様々な場面で使われます*ので、*各ノードの名前が何であるかを忘れないようにして下さい*。 + +次に、`droonga-http-server`をインストールします。 +これはHTTPのリクエストをDroongaネイティブのリクエストに変換するために必要な、フロントエンドとなるコンポーネントです。 +インストールスクリプトをダウンロードし、root権限で`bash`で実行して下さい: + +~~~ +# curl https://raw.githubusercontent.com/droonga/droonga-http-server/master/install.sh | \ + bash +... +Installing droonga-http-server from npmjs.org... +... +Preparing the user... +... +Setting up the configuration directory... +The droonga-engine service is detected on this node. +The droonga-http-server is configured to be connected +to this node (XXXXXXXX). +This node is configured with a hostname XXXXXXXX. + +Registering droonga-http-server as a service... +... +Successfully installed droonga-http-server. +~~~ + +ここまでの操作が終わったら、同じ操作をもう1台のコンピュータ `node1` (`192.168.100.51`) に対しても行います。 +これで、無事に2台のコンピュータをDroongaノードとして動作させるための準備が整いました。 + +### コンピュータが他のコンピュータからアクセスできるホスト名を持っていない場合…… {#accessible-host-name} + +各Droongaノードは、他のノードと通信するために、そのノード自身の*アクセス可能な名前*を把握している必要があります。 + +インストールスクリプトはそのノードのアクセス可能なホスト名を自動的に推測します。 +どのような値がそのノード自身のホスト名として認識されたかは、以下の手順で確認できます: + +~~~ +# cat ~droonga-engine/droonga/droonga-engine.yaml | grep host +host: XXXXXXXX +~~~ + +しかしながら、そのコンピュータが適切に設定されていないと、この自動認識に失敗することがあります。 +例えば、そのノードのホスト名が`node0`であると設定されているにも関わらず、他のノードが`node0`というホスト名から実際のIPアドレスを名前解決できないと、そのノードは他のノードから送られてくるメッセージを何も受信することができません。 + +そのような場合、以下のようにして、そのノード自身のIPアドレスを使ってノードを再設定する必要があります: + +~~~ +(on node0=192.168.100.50) +# host=192.168.100.50 +# droonga-engine-configure --quiet --reset-config --reset-catalog \ + --host=$host +# droonga-http-server-configure --quiet --reset-config \ + --droonga-engine-host-name=$host \ + --receive-host-name=$host + +(on node1=192.168.100.51) +# host=192.168.100.51 +... +~~~ + +この操作により、コンピュータ `node0` は `192.168.100.50` というホスト名のDroongaノード、コンピュータ `node1` は `192.168.100.51` というホスト名のDroongaノードとして設定されます。 +前述した通り、*ここで設定された名前は様々な場面で使われます*ので、*各ノードの名前が何であるかを忘れないようにして下さい*。 + +このチュートリアルでは、各コンピュータはお互いのホスト名`node0`と`node1`を正しく名前解決できるものと仮定します。 +あなたの環境ではホスト名の解決ができないという場合には、以下の説明の中の`node0`と`node1`は、実際のIPアドレス(例えば`192.168.100.50`と`192.168.100.51`)に読み替えて下さい。 + +ちなみに、インストールスクリプトに対しても、以下のように、環境変数を使って任意の値をホスト名として指定することができます: + +~~~ +(on node0=192.168.100.50) +# host=192.168.100.50 +# curl https://raw.githubusercontent.com/droonga/droonga-engine/master/install.sh | \ + HOST=$host bash +# curl https://raw.githubusercontent.com/droonga/droonga-http-server/master/install.sh | \ + ENGINE_HOST=$host HOST=$host bash + +(on node1=192.168.100.51) +# host=192.168.100.51 +... +~~~ + +この方法は、使おうとしているコンピュータがお互いのホスト名を名前解決できないことがあらかじめ分かっている場合に便利でしょう。 + +### 各ノードをクラスタとして動作するように設定する + +現時点で、これらのノードはまだ個別に動作する状態になっています。 +それでは、これらを1つのクラスタとして動作するように設定しましょう。 + +以下のようなコマンドを各ノードで実行して下さい: + +~~~ +# droonga-engine-catalog-generate --hosts=node0,node1 +~~~ + +当然ながら、`--hosts`オプションには各ノードの正しいホスト名を指定する必要があります。 +もしこれらのノードがIPアドレスをホスト名として設定されている場合には、コマンド列は以下のようになります: + +~~~ +# droonga-engine-catalog-generate --hosts=192.168.100.50,192.168.100.51 +~~~ + +これで、Droongaクラスタの準備が完了しました。 +2つのノードは1つのDroongaクラスタとして動作するための準備が完了しています。 + +引き続き、[クラスタの使い方の説明](#use)に進みましょう。 + + +## DroongaクラスタをHTTP経由(およびネイティブプロトコル)で使用する {#use} + +Droongaクラスタと通信する方法としては、HTTPとDroongaネイティブプロトコル(fluentdのプロトコルと同じ物)の2つの異なるインターフェースがあります。 + + * HTTPインターフェースは、Webアプリケーションから利用しやすいです。 + もしあなたのWebアプリケーションがGroongaのHTTPインターフェースを利用して開発されているのであれば、Droongaに簡単に移行できます。 + * ネイティブプロトコルはパフォーマンスが比較的良いですが、使い方が少し難しいです。 + しかし、クライアントライブラリや支援用のコマンドラインユーティリティがあります。 + +このセクションでの説明は、主にHTTPでの使い方について述べます。 + +### 各Droongaノードの上でのサービスの開始と停止 + +GroongaをHTTPサーバとして使う場合は、以下のように `-d` オプションを指定するだけでサーバを起動できます: + +~~~ +# groonga -p 10041 -d --protocol http /tmp/databases/db +~~~ + +一方、DroongaクラスタをHTTP経由で使うためには、各Droongaノードにおいて複数のサーバ・デーモンを起動する必要があります。 + +Droongaノードをインストールスクリプトを使ってセットアップした場合、デーモンは既に、`service`コマンドによって管理されるシステムのサービスとして設定されています。 +サービスを起動するには、以下のようなコマンドを各Droongaノードで実行して下さい: + +~~~ +# service droonga-engine start +# service droonga-http-server start +~~~ + +これらのコマンドにより、各サービスが動作し始めます。 +これで、2つのノードは1つのクラスタを形成し、お互いの状態を監視し合う状態になりました。 +もしノードが1つ停止しても、他のノードが生存していれば、それらの生存ノードだけでDroongaクラスタは動作し続けます。 +ですので、秘密裏のうちに機能停止したノードを復旧したりクラスタに復帰させたりすることができます。 + +重要な注意事項:`droonga-engine`と`droonga-http-server`のどちらも、起動時に自動的に依存性を解決するようになっています。 +例えば、これらは[Serf](https://www.serfdom.io/)のバイナリをダウンロードしてきます。 +すべての依存性が解決された後で初めて、これらのサービスは動作を開始します。 +ですので、初回起動時には、正常動作が始まるまでしばらく待つ必要があります。 + +クラスタが動作している事を、`system.status` コマンドを使って確認してみましょう。 +コマンドはHTTP経由で実行できます: + +~~~ +$ curl "http://node0:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +~~~ + +この結果は、2つのノードが正常に動作している事を示しています。 +Droongaはクラスタで動作するので、他のエンドポイントも同じ結果を返します。 + +~~~ +$ curl "http://node1:10041/droonga/system/status" | jq "." +{ + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." +} +~~~ + +`droonga-http-server`はクラスタ内のすべての`droonga-engine`に接続し、ロードバランサーのように、リクエストをそれらへ分配します。 +また、もしいくつかの`droonga-engine`が停止しても、`droonga-http-server`はそれらの死んだノードを自動的に回避するため、クラスタは正常に動作し続けます。 + +サービスを停止するには、以下のコマンドを各Droongaノード上で実行します: + +~~~ +# service droonga-engine stop +# service droonga-http-server stop +~~~ + +確認が終わったら、再度サービスを起動しておきましょう: + + +### Droongaクラスタとネイティブプロトコルで通信する + +ここまでに述べたHTTPでの使い方に対して、Gemパッケージ`droonga-client`に含まれるコマンドラインユーティリティの`droonca-request`コマンドを使うと、`droonga-engine`のサービスに対してネイティブ形式のメッセージを送ることができます。 +例えば、`droonga-http-server`のサービスを経由せずに`droonga-engine`ノードに`system.status`のリクエストを送る場合は以下の要領です: + +~~~ +$ echo '{"dataset":"Default","type":"system.status"}' | \ + droonga-request --host node0 --receiver-host node0 +Elapsed time: 0.023726995 +{ + "inReplyTo": "1430292510.4677904", + "statusCode": 200, + "type": "system.status.result", + "body": { + "nodes": { + "node0:10031/droonga": { + "status": "active" + }, + "node1:10031/droonga": { + "status": "active" + } + }, + "reporter": "..." + } +} +~~~ + +上記の通り、Droongaのネイティブ形式のメッセージはJSON形式で書かれます。 +これはGroongaのやり方と大きく異なるので、このチュートリアルではひとまず詳細は割愛します。 + + +### テーブル、カラム、インデックスの作成 + +以上の手順で、Groonga HTTPサーバ互換のHTTPサーバとして動作するDroongaクラスタができました。 + +リクエストの送信方法はGroongaサーバの場合と全く同じです。 +新しいテーブル `Store` を作るには、`table_create` コマンドにあたるGETリクエストを送信して下さい: + +~~~ +$ endpoint="http://node0:10041" +$ curl "$endpoint/d/table_create?name=Store&flags=TABLE_PAT_KEY&key_type=ShortText" | jq "." +[ + [ + 0, + 1401358896.360356, + 0.0035653114318847656 + ], + true +] +~~~ + +リクエストの送信先として、Droongaノード中でdroonga-http-serverが動作しているDroongaノードのどれか1つを指定する必要がある事に注意して下さい。 +言い換えると、接続先(エンドポイント)としてはクラスタ中のどのノードでも好きな物を使う事ができます。 +すべてのリクエストは、クラスタ中の適切なノードに配送されます。 + +さて、テーブルを正しく作成できました。 +`table_list` コマンドを使って、作成されたテーブルの情報を見てみましょう: + +~~~ +$ curl "$endpoint/d/table_list" | jq "." +[ + [ + 0, + 1401358908.9126804, + 0.001600027084350586 + ], + [ + [ + [ + "id", + "UInt32" + ], + [ + "name", + "ShortText" + ], + [ + "path", + "ShortText" + ], + [ + "flags", + "ShortText" + ], + [ + "domain", + "ShortText" + ], + [ + "range", + "ShortText" + ], + [ + "default_tokenizer", + "ShortText" + ], + [ + "normalizer", + "ShortText" + ] + ], + [ + 256, + "Store", + "/home/vagrant/droonga/000/db.0000100", + "TABLE_PAT_KEY|PERSISTENT", + "ShortText", + null, + null, + null + ] + ] +] +~~~ + +Droongaはクラスタで動作するので、他のエンドポイントも同じ結果を返します。 + +~~~ +$ curl "http://node1:10041/d/table_list" | jq "." +[ + [ + 0, + 1401358908.9126804, + 0.001600027084350586 + ], + [ + [ + [ + "id", + "UInt32" + ], + [ + "name", + "ShortText" + ], + [ + "path", + "ShortText" + ], + [ + "flags", + "ShortText" + ], + [ + "domain", + "ShortText" + ], + [ + "range", + "ShortText" + ], + [ + "default_tokenizer", + "ShortText" + ], + [ + "normalizer", + "ShortText" + ] + ], + [ + 256, + "Store", + "/home/vagrant/droonga/000/db.0000100", + "TABLE_PAT_KEY|PERSISTENT", + "ShortText", + null, + null, + null + ] + ] +] +~~~ + +次は、`column_create` コマンドを使って `Store` テーブルに `name` と `location` という新しいカラムを作ります: + +~~~ +$ curl "$endpoint/d/column_create?table=Store&name=name&flags=COLUMN_SCALAR&type=ShortText" | jq "." +[ + [ + 0, + 1401358348.6541538, + 0.0004096031188964844 + ], + true +] +$ curl "$endpoint/d/column_create?table=Store&name=location&flags=COLUMN_SCALAR&type=WGS84GeoPoint" | jq "." +[ + [ + 0, + 1401358359.084659, + 0.002511262893676758 + ], + true +] +~~~ + +インデックスも作成しましょう。 + +~~~ +$ curl "$endpoint/d/table_create?name=Term&flags=TABLE_PAT_KEY&key_type=ShortText&default_tokenizer=TokenBigram&normalizer=NormalizerAuto" | jq "." +[ + [ + 0, + 1401358475.7229664, + 0.002419710159301758 + ], + true +] +$ curl "$endpoint/d/column_create?table=Term&name=store_name&flags=COLUMN_INDEX|WITH_POSITION&type=Store&source=name" | jq "." +[ + [ + 0, + 1401358494.1656318, + 0.006799221038818359 + ], + true +] +$ curl "$endpoint/d/table_create?name=Location&flags=TABLE_PAT_KEY&key_type=WGS84GeoPoint" | jq "." +[ + [ + 0, + 1401358505.708896, + 0.0016951560974121094 + ], + true +] +$ curl "$endpoint/d/column_create?table=Location&name=store&flags=COLUMN_INDEX&type=Store&source=location" | jq "." +[ + [ + 0, + 1401358519.6187897, + 0.024788379669189453 + ], + true +] +~~~ + +結果を確認してみましょう: + +~~~ +$ curl "$endpoint/d/table_list" | jq "." +[ + [ + 0, + 1416390011.7194495, + 0.0015704631805419922 + ], + [ + [ + [ + "id", + "UInt32" + ], + [ + "name", + "ShortText" + ], + [ + "path", + "ShortText" + ], + [ + "flags", + "ShortText" + ], + [ + "domain", + "ShortText" + ], + [ + "range", + "ShortText" + ], + [ + "default_tokenizer", + "ShortText" + ], + [ + "normalizer", + "ShortText" + ] + ], + [ + 261, + "Location", + "/home/droonga-engine/droonga/databases/000/db.0000105", + "TABLE_PAT_KEY|PERSISTENT", + "WGS84GeoPoint", + null, + null, + null + ], + [ + 256, + "Store", + "/home/droonga-engine/droonga/databases/000/db.0000100", + "TABLE_PAT_KEY|PERSISTENT", + "ShortText", + null, + null, + null + ], + [ + 259, + "Term", + "/home/droonga-engine/droonga/databases/000/db.0000103", + "TABLE_PAT_KEY|PERSISTENT", + "ShortText", + null, + "TokenBigram", + "NormalizerAuto" + ] + ] +] +$ curl "$endpoint/d/column_list?table=Store" | jq "." +[ + [ + 0, + 1416390069.515929, + 0.001077413558959961 + ], + [ + [ + [ + "id", + "UInt32" + ], + [ + "name", + "ShortText" + ], + [ + "path", + "ShortText" + ], + [ + "type", + "ShortText" + ], + [ + "flags", + "ShortText" + ], + [ + "domain", + "ShortText" + ], + [ + "range", + "ShortText" + ], + [ + "source", + "ShortText" + ] + ], + [ + 256, + "_key", + "", + "", + "COLUMN_SCALAR", + "Store", + "ShortText", + [] + ], + [ + 258, + "location", + "/home/droonga-engine/droonga/databases/000/db.0000102", + "fix", + "COLUMN_SCALAR", + "Store", + "WGS84GeoPoint", + [] + ], + [ + 257, + "name", + "/home/droonga-engine/droonga/databases/000/db.0000101", + "var", + "COLUMN_SCALAR", + "Store", + "ShortText", + [] + ] + ] +] +$ curl "$endpoint/d/column_list?table=Term" | jq "." +[ + [ + 0, + 1416390110.143951, + 0.0013172626495361328 + ], + [ + [ + [ + "id", + "UInt32" + ], + [ + "name", + "ShortText" + ], + [ + "path", + "ShortText" + ], + [ + "type", + "ShortText" + ], + [ + "flags", + "ShortText" + ], + [ + "domain", + "ShortText" + ], + [ + "range", + "ShortText" + ], + [ + "source", + "ShortText" + ] + ], + [ + 259, + "_key", + "", + "", + "COLUMN_SCALAR", + "Term", + "ShortText", + [] + ], + [ + 260, + "store_name", + "/home/droonga-engine/droonga/databases/000/db.0000104", + "index", + "COLUMN_INDEX|WITH_POSITION", + "Term", + "Store", + [ + "name" + ] + ] + ] +] +$ curl "$endpoint/d/column_list?table=Location" | jq "." +[ + [ + 0, + 1416390163.0140722, + 0.0009713172912597656 + ], + [ + [ + [ + "id", + "UInt32" + ], + [ + "name", + "ShortText" + ], + [ + "path", + "ShortText" + ], + [ + "type", + "ShortText" + ], + [ + "flags", + "ShortText" + ], + [ + "domain", + "ShortText" + ], + [ + "range", + "ShortText" + ], + [ + "source", + "ShortText" + ] + ], + [ + 261, + "_key", + "", + "", + "COLUMN_SCALAR", + "Location", + "WGS84GeoPoint", + [] + ], + [ + 262, + "store", + "/home/droonga-engine/droonga/databases/000/db.0000106", + "index", + "COLUMN_INDEX", + "Location", + "Store", + [ + "location" + ] + ] + ] +] +~~~ + +### テーブルへのデータの読み込み + +それでは、`Store` テーブルにデータを読み込みましょう。 +まず、データを `stores.json` という名前のJSON形式のファイルとして用意します。 + +stores.json: + +~~~ +[ +["_key","name","location"], +["store0","1st Avenue & 75th St. - New York NY (W)","40.770262,-73.954798"], +["store1","76th & Second - New York NY (W)","40.771056,-73.956757"], +["store2","2nd Ave. & 9th Street - New York NY","40.729445,-73.987471"], +["store3","15th & Third - New York NY (W)","40.733946,-73.9867"], +["store4","41st and Broadway - New York NY (W)","40.755111,-73.986225"], +["store5","84th & Third Ave - New York NY (W)","40.777485,-73.954979"], +["store6","150 E. 42nd Street - New York NY (W)","40.750784,-73.975582"], +["store7","West 43rd and Broadway - New York NY (W)","40.756197,-73.985624"], +["store8","Macy's 35th Street Balcony - New York NY","40.750703,-73.989787"], +["store9","Macy's 6th Floor - Herald Square - New York NY (W)","40.750703,-73.989787"], +["store10","Herald Square- Macy's - New York NY","40.750703,-73.989787"], +["store11","Macy's 5th Floor - Herald Square - New York NY (W)","40.750703,-73.989787"], +["store12","80th & York - New York NY (W)","40.772204,-73.949862"], +["store13","Columbus @ 67th - New York NY (W)","40.774009,-73.981472"], +["store14","45th & Broadway - New York NY (W)","40.75766,-73.985719"], +["store15","Marriott Marquis - Lobby - New York NY","40.759123,-73.984927"], +["store16","Second @ 81st - New York NY (W)","40.77466,-73.954447"], +["store17","52nd & Seventh - New York NY (W)","40.761829,-73.981141"], +["store18","1585 Broadway (47th) - New York NY (W)","40.759806,-73.985066"], +["store19","85th & First - New York NY (W)","40.776101,-73.949971"], +["store20","92nd & 3rd - New York NY (W)","40.782606,-73.951235"], +["store21","165 Broadway - 1 Liberty - New York NY (W)","40.709727,-74.011395"], +["store22","1656 Broadway - New York NY (W)","40.762434,-73.983364"], +["store23","54th & Broadway - New York NY (W)","40.764275,-73.982361"], +["store24","Limited Brands-NYC - New York NY","40.765219,-73.982025"], +["store25","19th & 8th - New York NY (W)","40.743218,-74.000605"], +["store26","60th & Broadway-II - New York NY (W)","40.769196,-73.982576"], +["store27","63rd & Broadway - New York NY (W)","40.771376,-73.982709"], +["store28","195 Broadway - New York NY (W)","40.710703,-74.009485"], +["store29","2 Broadway - New York NY (W)","40.704538,-74.01324"], +["store30","2 Columbus Ave. - New York NY (W)","40.769262,-73.984764"], +["store31","NY Plaza - New York NY (W)","40.702802,-74.012784"], +["store32","36th and Madison - New York NY (W)","40.748917,-73.982683"], +["store33","125th St. btwn Adam Clayton & FDB - New York NY","40.808952,-73.948229"], +["store34","70th & Broadway - New York NY (W)","40.777463,-73.982237"], +["store35","2138 Broadway - New York NY (W)","40.781078,-73.981167"], +["store36","118th & Frederick Douglas Blvd. - New York NY (W)","40.806176,-73.954109"], +["store37","42nd & Second - New York NY (W)","40.750069,-73.973393"], +["store38","Broadway @ 81st - New York NY (W)","40.784972,-73.978987"], +["store39","Fashion Inst of Technology - New York NY","40.746948,-73.994557"] +] +~~~ + +データが準備できたら、`load` コマンドのPOSTリクエストとして送信します: + +~~~ +$ curl --data "@stores.json" "$endpoint/d/load?table=Store" | jq "." +[ + [ + 0, + 1401358564.909, + 0.158 + ], + [ + 40 + ] +] +~~~ + +これで、JSONファイル中のすべてのデータが正しく読み込まれます。 + +### テーブル中のデータを取り出す + +以上で、すべてのデータが準備できました。 + +試しに、`select` コマンドを使って最初の10レコードを取り出してみましょう: + +~~~ +$ curl "$endpoint/d/select?table=Store&output_columns=name&limit=10" | jq "." +[ + [ + 0, + 1401362059.7437818, + 4.935264587402344e-05 + ], + [ + [ + [ + 40 + ], + [ + [ + "name", + "ShortText" + ] + ], + [ + "1st Avenue & 75th St. - New York NY (W)" + ], + [ + "76th & Second - New York NY (W)" + ], + [ + "Herald Square- Macy's - New York NY" + ], + [ + "Macy's 5th Floor - Herald Square - New York NY (W)" + ], + [ + "80th & York - New York NY (W)" + ], + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "45th & Broadway - New York NY (W)" + ], + [ + "Marriott Marquis - Lobby - New York NY" + ], + [ + "Second @ 81st - New York NY (W)" + ], + [ + "52nd & Seventh - New York NY (W)" + ] + ] + ] +] +~~~ + +もちろん、`query` オプションを使って検索条件を指定する事もできます: + +~~~ +$ curl "$endpoint/d/select?table=Store&query=Columbus&match_columns=name&output_columns=name&limit=10" | jq "." +[ + [ + 0, + 1398670157.661574, + 0.0012705326080322266 + ], + [ + [ + [ + 2 + ], + [ + [ + "_key", + "ShortText" + ] + ], + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "2 Columbus Ave. - New York NY (W)" + ] + ] + ] +] +$ curl "$endpoint/d/select?table=Store&filter=name@'Ave'&output_columns=name&limit=10" | jq "." +[ + [ + 0, + 1398670586.193325, + 0.0003848075866699219 + ], + [ + [ + [ + 3 + ], + [ + [ + "_key", + "ShortText" + ] + ], + [ + "2nd Ave. & 9th Street - New York NY" + ], + [ + "84th & Third Ave - New York NY (W)" + ], + [ + "2 Columbus Ave. - New York NY (W)" + ] + ] + ] +] +~~~ + +## まとめ + +このチュートリアルでは、[Ubuntu Linux][Ubuntu]または[CentOS][]のコンピュータを使って[Droonga][]クラスタを構築しました。 +また、[Groonga][]サーバ互換のシステムとしてデータを読み込ませたり取り出したりすることにも成功しました。 + +現在の所、DroongaはGroonga互換のコマンドのうちいくつかの限定的な機能にのみ対応しています。 +詳細は[コマンドリファレンス][command reference]を参照して下さい。 + +続いて、[Droongaクラスタのデータをバックアップしたり復元したりする手順](../dump-restore/)を学びましょう。 + + [Ubuntu]: http://www.ubuntu.com/ + [CentOS]: https://www.centos.org/ + [Droonga]: https://droonga.org/ + [Groonga]: http://groonga.org/ + [command reference]: ../../reference/commands/ Added: ja/tutorial/1.1.2/index.md (+31 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/index.md 2015-11-15 23:29:56 +0900 (1ae5159) @@ -0,0 +1,31 @@ +--- +title: Droonga チュートリアル +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +## 初心者とGroonga利用者向け + + * [使ってみる/Groongaからの移行手順](groonga/) + * [実験用の仮想マシンを用意する手順](virtual-machines-for-experiments/) + * [データベースのバックアップと復元](dump-restore/) + * [既存クラスタへのreplicaの追加](add-replica/) + * [DroongaとGroongaのベンチマークの取り方](benchmark/) + +## 低レイヤのアプリケーション開発者向け + + * [低レイヤのコマンドの基本的な使い方](basic/) + +## プラグイン開発者向け + + * [プラグイン開発のチュートリアル](plugin-development/) + + Added: ja/tutorial/1.1.2/plugin-development/adapter/index.md (+701 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/plugin-development/adapter/index.md 2015-11-15 23:29:56 +0900 (31d1105) @@ -0,0 +1,701 @@ +--- +title: "プラグイン: リクエストとレスポンスを加工し、既存のコマンドに基づいた新しいコマンドを作成する" +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/plugin-development/adapter/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## チュートリアルのゴール + +Droongaプラグインを自分で開発するための手順を身につけましょう。 + +このページでは、Droongaプラグインによる「加工」(adaption)に焦点を当てます。 +最後には、小さな練習用のプラグインを開発して、既存の`search`コマンドに基づく新しいコマンド`storeSearch`を開発することになります。 + +## 前提条件 + +* [基本的な使い方のチュートリアル][basic tutorial] を完了している必要があります。 + + +## 入力メッセージの加工 + +まず`sample-logger`という簡単なロガープラグインを使って、適合フェーズに作用するプラグインを作りながら、基礎を学びましょう。 + +外部のシステムからDroonga Engineにやってくるリクエストを加工する必要がある場合があります。このようなときに、プラグインを利用できます。 + +このセクションでは、どのようにして*前適合フェーズ*のプラグインを作るのかを見てみていきます。 + +### ディレクトリの構造 + +[基本のチュートリアル][basic tutorial]で作成したシステムに対してプラグインを追加すると仮定します。 +先のチュートリアルでは、Droongaエンジンは `engine` ディレクトリ内に置かれていました。 + +プラグインは、適切な位置のディレクトリに置かれる必要があります。ディレクトリを作成しましょう: + +~~~ +# cd engine +# mkdir -p lib/droonga/plugins +~~~ + +ディレクトリを作成した後は、ディレクトリ構造は以下のようになります: + +~~~ +engine +├── catalog.json +├── fluentd.conf +└── lib + └── droonga + └── plugins +~~~ + + +### プラグインの作成 + +プラグイン用のコードは、*プラグイン自身の名前と同じ名前*のファイルに書く必要があります。 +これから作るプラグインの名前は`sample-logger`なので、コードは`droonga/plugins`ディレクトリ内の`sample-logger.rb`の中に書いていくことになります。 + +lib/droonga/plugins/sample-logger.rb: + +~~~ruby +require "droonga/plugin" + +module Droonga + module Plugins + module SampleLoggerPlugin + extend Plugin + register("sample-logger") + + class Adapter < Droonga::Adapter + # メッセージを加工するためのコードをここに書きます。 + end + end + end +end +~~~ + +このプラグインは、Droonga Engineに自分自身を登録する以外の事は何もしません。 + + * `sample-logger`は、このプラグイン自身の名前です。これは`catalog.json`の中で、プラグインを有効化するために使う事になります。 + * 上記の例のように、プラグインはモジュールとして定義する必要があります。 + * 前適合フェーズでの振る舞いは、*アダプター*と呼ばれるクラスとして定義します。 + アダプタークラスは必ず、プラグインのモジュールの名前空間の配下で、`Droonga::Adapter`のサブクラスとして定義する必要があります。 + + +### `catalog.json`でプラグインを有効化する + +プラグインを有効化するには、`catalog.json`を更新する必要があります。 +プラグインの名前`"sample-logger"`を、データセットの配下の`"plugins"`のリストに挿入します。例: + +catalog.json: + +~~~ +(snip) + "datasets": { + "Starbucks": { + (snip) + "plugins": ["sample-logger", "groonga", "crud", "search", "dump", "status"], +(snip) +~~~ + +注意:`"sample-logger"`は`"search"`よりも前に置く必要があります。これは、`sample-logger`プラグインが`search`に依存しているからです。Droonga Engineは前適合フェーズにおいて、プラグインを`catalog.json`で定義された順に適用しますので、プラグイン同士の依存関係は(今のところは)自分で解決しなくてはなりません。 + +### 実行と動作を確認する + +Droongaを起動しましょう。 +Rubyがあなたの書いたプラグインのコード群を見つけられるように、`RUBYLIB`環境変数に`./lib`を加えることに注意して下さい。 + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +そうしたら、Engineが正しく動作しているかを確かめます。 +まず、以下のようなJSON形式のリクエストを作成します。 + +search-columbus.json: + +~~~json +{ + "dataset" : "Starbucks", + "type" : "search", + "body" : { + "queries" : { + "stores" : { + "source" : "Store", + "condition" : { + "query" : "Columbus", + "matchTo" : "_key" + }, + "output" : { + "elements" : [ + "startTime", + "elapsedTime", + "count", + "attributes", + "records" + ], + "attributes" : ["_key"], + "limit" : -1 + } + } + } + } +} +~~~ + +これは[基本のチュートリアル](basic tutorial)において"Columbus"を検索する例に対応しています。 +Protocol Adapterへのリクエストは`"body"`要素の中に置かれていることに注意して下さい。 + +`droonga-request`コマンドを使ってリクエストをDroonga Engineに送信します: + +~~~ +# droonga-request --tag starbucks search-columbus.json +Elapsed time: 0.021544 +[ + "droonga.message", + 1392617533, + { + "inReplyTo": "1392617533.9644868", + "statusCode": 200, + "type": "search.result", + "body": { + "stores": { + "count": 2, + "records": [ + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "2 Columbus Ave. - New York NY (W)" + ] + ] + } + } + } +] +~~~ + +これが検索結果です。 + + +### プラグインを動作させる: ログをとる + +ここまでで作成したプラグインは、何もしない物でした。それでは、このプラグインを何か面白いことをする物にしましょう。 + +まず最初に、`search`のリクエストを捕まえてログ出力してみます。プラグインを以下のように更新して下さい: + +lib/droonga/plugins/sample-logger.rb: + +~~~ruby +(snip) + module SampleLoggerPlugin + extend Plugin + register("sample-logger") + + class Adapter < Droonga::Adapter + input_message.pattern = ["type", :equal, "search"] + + def adapt_input(input_message) + logger.info("SampleLoggerPlugin::Adapter", :message => input_message) + end + end + end +(snip) +~~~ + +`input_message.pattern`で始まる行は、設定です。 +この例では、プラグインを`"type":"search"`という情報を持つすべての入力メッセージに対して働くように定義しています。. +詳しくは[リファレンスマニュアルの設定のセクション](../../../reference/plugin/adapter/#config)を参照して下さい。 + +`adapt_input`メソッドは、パターンに当てはまるすべての入力メッセージに対して毎回呼ばれます。 +引数の`input_message`は、入力メッセージをラップした物です。 + +fluentdを再起動します: + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +前のセクションと同じリクエストを送信します: + +~~~ +# droonga-request --tag starbucks search-columbus.json +Elapsed time: 0.014714 +[ + "droonga.message", + 1392618037, + { + "inReplyTo": "1392618037.935901", + "statusCode": 200, + "type": "search.result", + "body": { + "stores": { + "count": 2, + "records": [ + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "2 Columbus Ave. - New York NY (W)" + ] + ] + } + } + } +] +~~~ + +すると、fluentdのログファイルである`fluentd.log`に以下のようなログが出力される事を確認できるでしょう。 + +~~~ +2014-02-17 15:20:37 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droonga::InputMessage:0x007f8ae3e1dd98 @raw_message={"dataset"=>"Starbucks", "type"=>"search", "body"=>{"queries"=>{"stores"=>{"source"=>"Store", "condition"=>{"query"=>"Columbus", "matchTo"=>"_key"}, "output"=>{"elements"=>["startTime", "elapsedTime", "count", "attributes", "records"], "attributes"=>["_key"], "limit"=>-1}}}}, "replyTo"=>{"type"=>"search.result", "to"=>"127.0.0.1:64591/droonga"}, "id"=>"1392618037.935901", "date"=>"2014-02-17 15:20:37 +0900", "appliedAdapters"=>[]}> +~~~ + +このログは、メッセージが`SampleLoggerPlugin::Adapter`によって受信されて、Droongaに渡されたことを示しています。実際のデータ処理の前に、この時点でメッセージを加工することができます。 + +### プラグインでメッセージを加工する + +レスポンスで返されるレコードの数を常に1つだけに制限したい場合、すべてのリクエストについて`limit`を`1`に指定する必要があります。プラグインを以下のように変更してみましょう: + +lib/droonga/plugins/sample-logger.rb: + +~~~ruby +(snip) + def adapt_input(input_message) + logger.info("SampleLoggerPlugin::Adapter", :message => input_message) + input_message.body["queries"]["stores"]["output"]["limit"] = 1 + end +(snip) +~~~ + +上の例のように、プラグインは`adapt_input`メソッドの引数として渡される`input_message`を通じて入力メッセージの内容を加工することができます。 +詳細は[当該メッセージの実装であるクラスのリファレンスマニュアル](../../../reference/plugin/adapter/#classes-Droonga-InputMessage)を参照して下さい。 + +fluentdを再起動します: + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +再起動後、レスポンスは`records`の値としてレコードを常に(最大で)1つだけ含むようになります。 + +先の場合と同じリクエストを投げてみましょう: + +~~~ +# droonga-request --tag starbucks search-columbus.json +Elapsed time: 0.017343 +[ + "droonga.message", + 1392618279, + { + "inReplyTo": "1392618279.0578449", + "statusCode": 200, + "type": "search.result", + "body": { + "stores": { + "count": 2, + "records": [ + [ + "Columbus @ 67th - New York NY (W)" + ] + ] + } + } + } +] +~~~ + +`count`が依然として`2`であることに注意して下さい。これは、`limit`が`count`には影響を与えないという`search`コマンド自体の仕様によるものです。`search`コマンドの詳細については[`search`コマンドのリファレンスマニュアル][search]を参照して下さい。 + +すると、fluentdのログファイルである`fluentd.log`に以下のようなログが出力される事を確認できるでしょう。 + +~~~ +2014-02-17 15:24:39 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droonga::InputMessage:0x007f956685c908 @raw_message={"dataset"=>"Starbucks", "type"=>"search", "body"=>{"queries"=>{"stores"=>{"source"=>"Store", "condition"=>{"query"=>"Columbus", "matchTo"=>"_key"}, "output"=>{"elements"=>["startTime", "elapsedTime", "count", "attributes", "records"], "attributes"=>["_key"], "limit"=>-1}}}}, "replyTo"=>{"type"=>"search.result", "to"=>"127.0.0.1:64616/droonga"}, "id"=>"1392618279.0578449", "date"=>"2014-02-17 15:24:39 +0900", "appliedAdapters"=>[]}> +~~~ + + +## 出力メッセージの加工 + +Droonga Engineからの出力メッセージ(例えば検索結果など)を加工したい場合は、別のメソッドを定義することでそれを実現できます。 +このセクションでは、出力メッセージを加工するメソッドを定義してみましょう。 + + +### 出力のメッセージを加工するメソッドを追加する + +`search`コマンドの結果のログを取ってみましょう。 +出力メッセージを処理するために、`adapt_output`メソッドを定義します。 +説明を簡単にするために、ここでは`adapt_input`メソッドの定義を一旦削除します。 + +lib/droonga/plugins/sample-logger.rb: + +~~~ruby +(snip) + module SampleLoggerPlugin + extend Plugin + register("sample-logger") + + class Adapter < Droonga::Adapter + input_message.pattern = ["type", :equal, "search"] + + def adapt_output(output_message) + logger.info("SampleLoggerPlugin::Adapter", :message => output_message) + end + end + end +(snip) +~~~ + +`adapt_output`メソッドは、そのプラグイン自身によって捕捉された入力メッセージに起因して送出された出力メッセージに対してのみ呼ばれます(マッチングパターンのみが指定されていて、`adapt_input`メソッドが定義されていない場合であっても)。 +詳細は[プラグイン開発APIのリファレンスマニュアル](../../../reference/plugin/adapter/)を参照して下さい。 + +### 実行する + +fluentdを再起動しましょう: + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +次に、検索リクエストを送ります(前のセクションと同じJSONをリクエストとして使います): + +~~~ +# droonga-request --tag starbucks search-columbus.json +Elapsed time: 0.015491 +[ + "droonga.message", + 1392619269, + { + "inReplyTo": "1392619269.184789", + "statusCode": 200, + "type": "search.result", + "body": { + "stores": { + "count": 2, + "records": [ + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "2 Columbus Ave. - New York NY (W)" + ] + ] + } + } + } +] +~~~ + +fluentdのログは以下のようになっているはずです: + +~~~ +2014-02-17 15:41:09 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droonga::OutputMessage:0x007fddcad4d5a0 @raw_message={"dataset"=>"Starbucks", "type"=>"dispatcher", "body"=>{"stores"=>{"count"=>2, "records"=>[["Columbus @ 67th - New York NY (W)"], ["2 Columbus Ave. - New York NY (W)"]]}}, "replyTo"=>{"type"=>"search.result", "to"=>"127.0.0.1:64724/droonga"}, "id"=>"1392619269.184789", "date"=>"2014-02-17 15:41:09 +0900", "appliedAdapters"=>["Droonga::Plugins::SampleLoggerPlugin::Adapter", "Droonga::Plugins::Error::Adapter"]}> +~~~ + +ここには、`search`の結果が`adapt_output`メソッドに渡された事(そしてログ出力された事)が示されています。 + + +### 結果を適合フェーズで加工する + +*後適合フェーズ*において、結果を加工してみましょう。 +例えば、リクエストに対する処理が完了した時刻を示す`completedAt`というアトリビュートを加えるとします。 +プラグインを以下のように更新して下さい: + +lib/droonga/plugins/sample-logger.rb: + +~~~ruby +(snip) + def adapt_output(output_message) + logger.info("SampleLoggerPlugin::Adapter", :message => output_message) + output_message.body["stores"]["completedAt"] = Time.now + end +(snip) +~~~ + +上の例のように、出力メッセージは`adapt_output`メソッドの引数として渡される`output_message`を通じて加工することができます。 +詳細は[当該メッセージの実装のクラスのリファレンスマニュアル](../../../reference/plugin/adapter/#classes-Droonga-OutputMessage)を参照して下さい。 + +fluentdを再起動します: + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +同じ検索リクエストを送ってみましょう: + +~~~ +# droonga-request --tag starbucks search-columbus.json +Elapsed time: 0.013983 +[ + "droonga.message", + 1392619528, + { + "inReplyTo": "1392619528.235121", + "statusCode": 200, + "type": "search.result", + "body": { + "stores": { + "count": 2, + "records": [ + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "2 Columbus Ave. - New York NY (W)" + ] + ], + "completedAt": "2014-02-17T06:45:28.247669Z" + } + } + } +] +~~~ + +リクエストの処理が完了した時刻を含むアトリビュートである`completedAt`が追加された事を確認できました。 +`fluentd.log`には以下のように出力されているはずです: + +~~~ +2014-02-17 15:45:28 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droonga::OutputMessage:0x007fd384f3ab60 @raw_message={"dataset"=>"Starbucks", "type"=>"dispatcher", "body"=>{"stores"=>{"count"=>2, "records"=>[["Columbus @ 67th - New York NY (W)"], ["2 Columbus Ave. - New York NY (W)"]]}}, "replyTo"=>{"type"=>"search.result", "to"=>"127.0.0.1:64849/droonga"}, "id"=>"1392619528.235121", "date"=>"2014-02-17 15:45:28 +0900", "appliedAdapters"=>["Droonga::Plugins::SampleLoggerPlugin::Adapter", "Droonga::Plugins::Error::Adapter"]}> +~~~ + + +## 入出力メッセージの加工 + +ここまでで、前適合フェーズと後適合フェーズで動作するプラグインの基本を学びました。 +それでは、より実践的なプラグインを開発してみることにしましょう。 + +Droongaの`search`コマンドを見た時、目的に対していささか柔軟すぎるという印象を持ったことと思います +そこで、ここではアプリケーション固有の単純なインターフェースを持つコマンドとして、`search`コマンドをラップする`storeSearch`というコマンドを、`store-search`というプラグインで追加していくことにします。 + +### シンプルなリクエストを受け取る + +まず最初に、`store-search`プラグインを作ります。 +思い出して下さい、プラグインを実装するコードは、これから作ろうとしているプラグインと同じ名前のファイルに書かなくてはなりませんでしたよね。 +ですので、実装を書くファイルは`droonga/plugins`ディレクトリに置かれた`store-search.rb`となります。`StoreSearchPlugin`を以下のように定義しましょう: + +lib/droonga/plugins/store-search.rb: + +~~~ruby +require "droonga/plugin" + +module Droonga + module Plugins + module StoreSearchPlugin + extend Plugin + register("store-search") + + class Adapter < Droonga::Adapter + input_message.pattern = ["type", :equal, "storeSearch"] + + def adapt_input(input_message) + logger.info("StoreSearchPlugin::Adapter", :message => input_message) + + query = input_message.body["query"] + logger.info("storeSearch", :query => query) + + body = { + "queries" => { + "stores" => { + "source" => "Store", + "condition" => { + "query" => query, + "matchTo" => "_key", + }, + "output" => { + "elements" => [ + "startTime", + "elapsedTime", + "count", + "attributes", + "records", + ], + "attributes" => [ + "_key", + ], + "limit" => -1, + } + } + } + } + + input_message.type = "search" + input_message.body = body + end + end + end + end +end +~~~ + +次に、プラグインを有効化するために`catalog.json`を更新します。 +先程作成した`sample-logger`は削除しておきます。 + +catalog.json: + +~~~ +(snip) + "datasets": { + "Starbucks": { + (snip) + "plugins": ["store-search", "groonga", "crud", "search", "dump", "status"], +(snip) +~~~ + +思い出して下さい、`"store-search"`は`"search"`に依存しているので、`"search"`よりも前に置く必要があります。 + +fluentdを再起動します: + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +これで、以下のようなリクエストで新しいコマンドを使えるようになりました: + +store-search-columbus.json: + +~~~json +{ + "dataset" : "Starbucks", + "type" : "storeSearch", + "body" : { + "query" : "Columbus" + } +} +~~~ + +リクエストを発行するために、以下のようにコマンドを実行しましょう: + +~~~ +# droonga-request --tag starbucks store-search-columbus.json +Elapsed time: 0.01494 +[ + "droonga.message", + 1392621168, + { + "inReplyTo": "1392621168.0119512", + "statusCode": 200, + "type": "storeSearch.result", + "body": { + "stores": { + "count": 2, + "records": [ + [ + "Columbus @ 67th - New York NY (W)" + ], + [ + "2 Columbus Ave. - New York NY (W)" + ] + ] + } + } + } +] +~~~ + +この時、`fluentd.log`には以下のようなログが出力されているはずです: + +~~~ +2014-02-17 16:12:48 +0900 [info]: StoreSearchPlugin::Adapter message=#<Droonga::InputMessage:0x007fe4791d3958 @raw_message={"dataset"=>"Starbucks", "type"=>"storeSearch", "body"=>{"query"=>"Columbus"}, "replyTo"=>{"type"=>"storeSearch.result", "to"=>"127.0.0.1:49934/droonga"}, "id"=>"1392621168.0119512", "date"=>"2014-02-17 16:12:48 +0900", "appliedAdapters"=>[]}> +2014-02-17 16:12:48 +0900 [info]: storeSearch query="Columbus" +~~~ + +以上の手順で、単純なリクエストによって店舗の検索を行えるようになりました。 + +注意:レスポンスのメッセージの`"type"`の値が`"search.result"`から`"storeSearch.result"`に変わっていることに注目して下さい。これは、このレスポンスが、`type`が`"storeSearch"`であるリクエストに起因して発生した物であるために、Droonga Engineによって自動的に`"(入力メッセージのtype).result"`という`type`が設定されたからです。言い換えると、出力メッセージの`type`は、`adapt_input`での`input_message.type = "search"`のような方法でわざわざ自分で設定し直す必要はありません。 + +### シンプルなレスポンスを返す + +次に、結果をより単純な形で、単に店舗の名前の配列だけを返すだけという物にしてみましょう。 + +`adapt_output`を以下のように定義して下さい。 + +lib/droonga/plugins/store-search.rb: + +~~~ruby +(snip) + module StoreSearchPlugin + extend Plugin + register("store-search") + + class Adapter < Droonga::Adapter + (snip) + + def adapt_output(output_message) + logger.info("StoreSearchPlugin::Adapter", :message => output_message) + + records = output_message.body["stores"]["records"] + simplified_results = records.flatten + + output_message.body = simplified_results + end + end + end +(snip) +~~~ + +`adapt_output`メソッドは、そのプラグインによって捕捉された入力メッセージに対応する出力メッセージのみを受け取ります。 + +fluentdを再起動します: + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +リクエストを送ってみましょう: + +~~~ +# droonga-request --tag starbucks store-search-columbus.json +Elapsed time: 0.014859 +[ + "droonga.message", + 1392621288, + { + "inReplyTo": "1392621288.158763", + "statusCode": 200, + "type": "storeSearch.result", + "body": [ + "Columbus @ 67th - New York NY (W)", + "2 Columbus Ave. - New York NY (W)" + ] + } +] +~~~ + +`fluentd.log`には以下のようなログが出力されているはずです: + +~~~ +2014-02-17 16:14:48 +0900 [info]: StoreSearchPlugin::Adapter message=#<Droonga::InputMessage:0x007ffb8ada9d68 @raw_message={"dataset"=>"Starbucks", "type"=>"storeSearch", "body"=>{"query"=>"Columbus"}, "replyTo"=>{"type"=>"storeSearch.result", "to"=>"127.0.0.1:49960/droonga"}, "id"=>"1392621288.158763", "date"=>"2014-02-17 16:14:48 +0900", "appliedAdapters"=>[]}> +2014-02-17 16:14:48 +0900 [info]: storeSearch query="Columbus" +2014-02-17 16:14:48 +0900 [info]: StoreSearchPlugin::Adapter message=#<Droonga::OutputMessage:0x007ffb8ad78e48 @raw_message={"dataset"=>"Starbucks", "type"=>"dispatcher", "body"=>{"stores"=>{"count"=>2, "records"=>[["Columbus @ 67th - New York NY (W)"], ["2 Columbus Ave. - New York NY (W)"]]}}, "replyTo"=>{"type"=>"storeSearch.result", "to"=>"127.0.0.1:49960/droonga"}, "id"=>"1392621288.158763", "date"=>"2014-02-17 16:14:48 +0900", "appliedAdapters"=>["Droonga::Plugins::StoreSearchPlugin::Adapter", "Droonga::Plugins::Error::Adapter"], "originalTypes"=>["storeSearch"]}> +~~~ + +このように、単純化されたレスポンスを受け取ることができました。 + +ここで解説したように、アダプターはアプリケーション固有の検索機能を実装するために利用できます。 + +## まとめ + +既存のコマンドと独自のアダプターのみを使って新しいコマンドを追加する方法について学びました。 +その過程で、入力メッセージと出力メッセージの両方について、どのように受け取り加工するのかについても学びました。 + +詳細は[リファレンスマニュアル](../../../reference/plugin/adapter/)を参照して下さい。 + + + [basic tutorial]: ../../basic/ + [overview]: ../../../overview/ + [search]: ../../../reference/commands/select/ Added: ja/tutorial/1.1.2/plugin-development/handler/index.md (+542 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/plugin-development/handler/index.md 2015-11-15 23:29:56 +0900 (e79a271) @@ -0,0 +1,542 @@ +--- +title: "プラグイン: 全てのパーティション上でリクエストを処理し、ストレージを操作する新たなコマンドを追加する" +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/plugin-development/handler/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## チュートリアルのゴール + +このチュートリアルでは、各ボリュームでのhadling phaseにおいて分散された処理を実行するプラグインを開発するための方法を学びます。 +言い換えると、このチュートリアルでは *新しいコマンドをDroonga Engineに加える方法* を説明します。 + +## 前提条件 + +* [adaption phaseのチュートリアル][adapter]を完了していること。 + +## リクエストのハンドリング + +適合フェーズからリクエストが転送されてくると、Droonga Engineは*処理フェーズ(processing phase)*に入ります。 + +処理フェーズでは、Droonga Engineはリクエストを「ステップ」ごとに段階的に処理します。 +1つの *ステップ* は、*立案フェーズ*、*配布フェーズ*、*ハンドリング・フェーズ*、そして *集約フェーズ* という4つのフェーズから成り立っています。 + + * *立案フェーズ* では、Droonga Engineはリクエストを処理するための複数のより小さなステップを生成します。 + 単純なコマンドでは、このフェーズのためのコードを書く必要はありません。その場合には、リクエストを処理するためのステップが1つだけ存在するということになります。 + * *配布フェーズ* では、Droonga Engineは、リクエストを処理するためのタスクを表すメッセージを複数のボリュームに配布します。 + (この処理は完全にDroonga Engine自身によって行われるため、このフェーズはプラグインでの拡張はできません。) + * *ハンドリング・フェーズ*では、*各single volumeが、配布された単一のタスクメッセージを入力として処理して、その結果を返します*。 + ストレージへの読み書きが実際に発生するのは、この時になります。 + 実際に、いくつかのコマンド(例えば `search`、`add`、`create_table` など)はこのタイミングでストレージの読み書きを行っています。 + * *集約フェーズ* では、Droonga Engineが各ボリュームから返された結果を集約して、単一の結果に統合します。 + Droonga Engineは汎用の便利なcollectorをいくつか含んでいるため、多くの場合において、あなたはこのフェーズのためのコードを書く必要はありません。 + +すべてのステップの処理が終了すると、Droonga Engineは結果を後適合フェーズへと転送します。 + +ハンドリング・フェーズでの操作を定義するクラスは、*ハンドラー*と呼ばれます。 +簡単に言うと、新しいハンドラーを追加するということは、新しいコマンドを追加するということを意味します。 + + + + + + +## 読み取り専用のコマンド `countRecords` を設計する + +このチュートリアルでは、新しい独自のコマンド `countRecords` を実装することにします。 +まず、コマンドの仕様を設計しましょう。 + +このコマンドは、個々のsingle volumeにおける指定テーブルの全レコードの数を報告します。 +これは、クラスタ内でどのようにレコードが分散されているかを調べる助けになるでしょう。 +このコマンドはデータベースの内容を何も変更しないので、これは*読み取り専用のコマンド*と言うことができます。 + +リクエストは、以下のようにテーブル名を必ず1つ含まなくてはなりません + +~~~json +{ + "dataset" : "Starbucks", + "type" : "countRecords", + "body" : { + "table": "Store" + } +} +~~~ + +上記のような内容のJSON形式のファイル `count-records.json` を作成します。 +以降の検証では、このファイルを使い続けていきましょう。 + +レスポンスは、各single volumeごとのそのテーブルにあるレコードの数を含んでいなくてはなりません。 +これは以下のように、配列として表現できます: + +~~~json +{ + "inReplyTo": "(message id)", + "statusCode": 200, + "type": "countRecords.result", + "body": [10, 10] +} +~~~ + +ボリュームが2つある場合、20個のレコードが均等に保持されているはずなので、配列は上記のように2つの要素を持つことになるでしょう。 +この例は、各ボリュームがレコードを10個ずつ保持している事を示しています。 + +それでは、ここまでで述べたような形式のリクエストを受け付けて上記のようなレスポンスを返す、というプラグインを作っていきましょう。 + + +### ディレクトリ構成 + +プラグインのディレクトリ構成は、[適合フェーズ用のプラグインのチュートリアル][adapter]での説明と同じ様式に則ります。 +`count-records.rb` というファイルとして、`count-records` プラグインを作りましょう。ディレクトリツリーは以下のようになります: + +~~~ +lib +└── droonga + └── plugins + └── count-records.rb +~~~ + +次に、以下のようにしてプラグインの骨組みを作ります: + +lib/droonga/plugins/count-records.rb: + +~~~ruby +require "droonga/plugin" + +module Droonga + module Plugins + module CountRecordsPlugin + extend Plugin + register("count-records") + end + end +end +~~~ + +### コマンドのための「ステップ」を定義する + +以下のようにして、プラグインの中で新しいコマンド `countRecords` のための「ステップ」を定義します: + +lib/droonga/plugins/count-records.rb: + +~~~ruby +require "droonga/plugin" + +module Droonga + module Plugins + module CountRecordsPlugin + extend Plugin + register("count-records") + + define_single_step do |step| + step.name = "countRecords" + end + end + end +end +~~~ + +`step.name` の値は、コマンド自身の名前と同じです。 +今のところは、コマンドの名前を定義しただけです。 +それ以上のことはしていません。 + +### ハンドリングの仕方を定義する + +このコマンドはハンドラーを持っていないため、まだ何も処理が行われません。 +それではコマンドの挙動を定義しましょう。 + +lib/droonga/plugins/count-records.rb: + +~~~ruby +require "droonga/plugin" + +module Droonga + module Plugins + module CountRecordsPlugin + extend Plugin + register("count-records") + + define_single_step do |step| + step.name = "countRecords" + step.handler = :Handler + end + + class Handler < Droonga::Handler + def handle(message) + [0] + end + end + end + end +end +~~~ + +`Handler` というクラスは、新しいコマンドのためのハンドラークラスです。 + + * ハンドラークラスは、組み込みのクラス `Droonga::Handler` を継承してなければなりません。 + * ハンドラークラスは、リクエストをどのように扱うかの処理を実装します。 + インスタンスメソッド `#handle` が実際にリクエストを処理します。 + +現時点で、このハンドラーは何も処理を行わず、単に数値1つからなる配列を含む処理結果を返すだけです。 +戻り値はレスポンスのbodyを組み立てるのに使われます。 + +The handler is bound to the step with the configuration `step.handler`. +Because we define the class `Handler` after `define_single_step`, we specify the handler class with a symbol `:Handler`. +If you define the handler class before `define_single_step`, then you can write as `step.handler = Handler` simply. +Moreover, a class path string like `"OtherPlugin::Handler"` is also available. + +Then, we also have to bind a collector to the step, with the configuration `step.collector`. + +lib/droonga/plugins/count-records.rb: + +~~~ruby +# (snip) + define_single_step do |step| + step.name = "countRecords" + step.handler = :Handler + step.collector = Collectors::Sum + end +# (snip) +~~~ + +The `Collectors::Sum` is one of built-in collectors. +It merges results returned from handler instances for each volume to one result. + + +### `catalog.json`でプラグインを有効化する + +Update catalog.json to activate this plugin. +Add `"count-records"` to `"plugins"`. + +~~~ +(snip) + "datasets": { + "Starbucks": { + (snip) + "plugins": ["count-records", "groonga", "crud", "search", "dump", "status"], +(snip) +~~~ + +### 実行と動作を確認する + +Let's get Droonga started. +Note that you need to specify ./lib directory in RUBYLIB environment variable in order to make ruby possible to find your plugin. + + # kill $(cat fluentd.pid) + # RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid + +Then, send a request message for the `countRecords` command to the Droonga Engine. + +~~~ +# droonga-request --tag starbucks count-records.json +Elapsed time: 0.01494 +[ + "droonga.message", + 1392621168, + { + "inReplyTo": "1392621168.0119512", + "statusCode": 200, + "type": "countRecords.result", + "body": [ + 0, + 0, + 0 + ] + } +] +~~~ + +You'll get a response message like above. +Look at these points: + + * The `type` of the response becomes `countRecords.result`. + It is automatically named by the Droonga Engine. + * The format of the `body` is same to the returned value of the handler's `handle` method. + +There are three elements in the array. Why? + + * Remember that the `Starbucks` dataset was configured with two replicas and three sub volumes for each replica, in the `catalog.json` of [the basic tutorial][basic]. + * Because it is a read-only command, a request is delivered to only one replica (and it is chosen at random). + Then only three single volumes receive the command, so only three results appear, not six. + (TODO: I have to add a figure to indicate active nodes: [000, 001, 002, 010, 011, 012] => [000, 001, 002]) + * The `Collectors::Sum` collects them. + Those three results are joined to just one array by the collector. + +As the result, just one array with three elements appears in the final response. + +### Read-only access to the storage + +Now, each instance of the handler class always returns `0` as its result. +Let's implement codes to count up the number of records from the actual storage. + +lib/droonga/plugins/count-records.rb: + +~~~ruby +# (snip) + class Handler < Droonga::Handler + def handle(message) + request = message.request + table_name = request["table"] + table = @context[table_name] + count = table.size + [count] + end + end +# (snip) +~~~ + +Look at the argument of the `handle` method. +It is different from the one an adapter receives. +A handler receives a message meaning a distributed task. +So you have to extract the request message from the distributed task by the code `request = message.request`. + +The instance variable `@context` is an instance of `Groonga::Context` for the storage of the corresponding single volume. +See the [class reference of Rroonga][Groonga::Context]. +You can use any feature of Rroonga via `@context`. +For now, we simply access to the table itself by its name and read the value of its `size` method - it returns the number of records. + +Then, test it. +Restart the Droonga Engine and send the request again. + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +# droonga-request --tag starbucks count-records.json +Elapsed time: 0.01494 +[ + "droonga.message", + 1392621168, + { + "inReplyTo": "1392621168.0119512", + "statusCode": 200, + "type": "countRecords.result", + "body": [ + 14, + 15, + 11 + ] + } +] +~~~ + +Because there are totally 40 records, they are stored evenly like above. + +## Design a read-write command `deleteStores` + +Next, let's add another new custom command `deleteStores`. + +The command deletes records of the `Store` table, from the storage. +Because it modifies something in existing storage, it is a *read-write command*. + +The request must have the condition to select records to be deleted, like: + +~~~json +{ + "dataset" : "Starbucks", + "type" : "deleteStores", + "body" : { + "keyword": "Broadway" + } +} +~~~ + +Any record including the given keyword `"Broadway"` in its `"key"` is deleted from the storage of all volumes. + +Create a JSON file `delete-stores-broadway.json` with the content above. +We'll use it for testing. + +The response must have a boolean value to indicate "success" or "fail", like: + +~~~json +{ + "inReplyTo": "(message id)", + "statusCode": 200, + "type": "deleteStores.result", + "body": true +} +~~~ + +If the request is successfully processed, the `body` becomes `true`. Otherwise `false`. +The `body` is just one boolean value, because we don't have to receive multiple results from volumes. + + +### ディレクトリの構造 + +Now let's create the `delete-stores` plugin, as the file `delete-stores.rb`. The directory tree will be: + +~~~ +lib +└── droonga + └── plugins + └── delete-stores.rb +~~~ + +次に、以下のようにしてプラグインの骨組みを作ります: + +lib/droonga/plugins/delete-stores.rb: + +~~~ruby +require "droonga/plugin" + +module Droonga + module Plugins + module DeleteStoresPlugin + extend Plugin + register("delete-stores") + end + end +end +~~~ + + +### コマンドのための「ステップ」を定義する + +Define a "step" for the new `deleteStores` command, in your plugin. Like: + +lib/droonga/plugins/delete-stores.rb: + +~~~ruby +require "droonga/plugin" + +module Droonga + module Plugins + module DeleteStoresPlugin + extend Plugin + register("delete-stores") + + define_single_step do |step| + step.name = "deleteStores" + step.write = true + end + end + end +end +~~~ + +Look at a new configuration `step.write`. +Because this command modifies the storage, we must indicate it clearly. + +### ハンドリングの仕方を定義する + +Let's define the handler. + +lib/droonga/plugins/delete-stores.rb: + +~~~ruby +require "droonga/plugin" + +module Droonga + module Plugins + module DeleteStoresPlugin + extend Plugin + register("delete-stores") + + define_single_step do |step| + step.name = "deleteStores" + step.write = true + step.handler = :Handler + step.collector = Collectors::And + end + + class Handler < Droonga::Handler + def handle(message) + request = message.request + keyword = request["keyword"] + table = @context["Store"] + table.delete do |record| + record.key =~ keyword + end + true + end + end + end + end +end +~~~ + +Remember, you have to extract the request message from the received task message. + +The handler finds and deletes existing records which have the given keyword in its "key", by the [API of Rroonga][Groonga::Table_delete]. + +And, the `Collectors::And` is bound to the step by the configuration `step.collector`. +It is is also one of built-in collectors, and merges boolean values returned from handler instances for each volume, to one boolean value. + +### `catalog.json`でプラグインを有効化する + +Update catalog.json to activate this plugin. +Add `"delete-stores"` to `"plugins"`. + +~~~ +(snip) + "datasets": { + "Starbucks": { + (snip) + "plugins": ["delete-stores", "count-records", "groonga", "crud", "search", "dump", "status"], +(snip) +~~~ + +### 実行と動作を確認する + +Restart the Droonga Engine and send the request. + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +# droonga-request --tag starbucks count-records.json +Elapsed time: 0.01494 +[ + "droonga.message", + 1392621168, + { + "inReplyTo": "1392621168.0119512", + "statusCode": 200, + "type": "deleteStores.result", + "body": true + } +] +~~~ + +Because results from volumes are unified to just one boolean value, the response's `body` is a `true`. +As the verification, send the request of `countRecords` command. + +~~~ +# droonga-request --tag starbucks count-records.json +Elapsed time: 0.01494 +[ + "droonga.message", + 1392621168, + { + "inReplyTo": "1392621168.0119512", + "statusCode": 200, + "type": "countRecords.result", + "body": [ + 7, + 13, + 6 + ] + } +] +~~~ + +Note, the number of records are smaller than the previous result. +This means that four or some records are deleted from each volume. + +## まとめ + +We have learned how to add a new simple command working around the data. +In the process, we also have learned how to create plugins working in the handling phrase. + + + [adapter]: ../adapter + [basic]: ../basic + [Groonga::Context]: http://ranguba.org/rroonga/en/Groonga/Context.html + [Groonga::Table_delete]: http://ranguba.org/rroonga/en/Groonga/Table.html#delete-instance_method Added: ja/tutorial/1.1.2/plugin-development/index.md (+92 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/plugin-development/index.md 2015-11-15 23:29:56 +0900 (917a816) @@ -0,0 +1,92 @@ +--- +title: Droongaプラグイン開発チュートリアル +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/plugin-development/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## チュートリアルのゴール + +Droongaプラグインの作り方を理解します。 +[基本的な使い方のチュートリアル][basic tutorial]を完了している必要があります。 + + +## プラグインとは + +プラグインはDroongaの中でもっとも重要なコンセプトの一つです。 +プラグインがDroongaを柔軟なものにしています。 + +多くの現実的なデータ処理タスクでは、問題に応じたデータの取り扱いが必要です。これを汎用の方法で解決するのは簡単ではありせん。 + + * 外部のシステムと連携するために、入力のリクエスト形式を変更する必要があるかもしれません。外部のシステムが理解できるような形式で出力するために、出力を加工する必要があるかもしれません。 + * Droongaが標準で提供する機能よりもさらに複雑なデータ操作を、ストレージに直接アクセスしながら効率よく行う必要があるかもしれません。 + * Droongaのデータ分散と回収ロジックをコントロールすることで、Droongaの分散性能を活かした高度なアプリケーションを構築する必要があるかもしれません。 + +このような場合にプラグインを利用することができます。 + +## Droongaエンジンにおけるプラガブルな操作 + +Droonga Engineにはプラガブルなフェーズが大きく分けて2つあり、そのうちの1つは3つのサブフェーズから構成されます。プラグインの観点からすると、都合1つから4つの操作に処理を追加することができます。 + +適合フェーズ(adaption phase) +: このフェーズでは、プラグインは入力のリクエストと出力のレスポンスを加工できます。 + +処理フェーズ(processing phase) +: このフェーズでは、プラグインはそれぞれのボリューム上で入力のリクエストを逐次処理します。 + +処理フェーズにはプラグインでの拡張が可能な3つのサブフェーズがあります: + +ハンドリング・フェーズ(handling phase) +: このフェーズでは、プラグインは低レベルのデータ処理、たとえばデータベース操作などを行うことができます。 + +立案フェーズ(planning phase) +: このフェーズでは、プラグインは入力のリクエストを複数のステップに分割できます。 + +集約フェーズ(collection phase) +: このフェーズでは、プラグインはステップから得られた結果をマージして一つの結果を生成できます。 + +上記の説明は、Droongaシステムの設計に基いているので、少々わかりづらいかもしれません。 +ここでは、プラグインでの拡張が可能な操作という観点から離れて、プラグインで何をしたいのかという観点から見てみましょう。 + +既に存在するコマンドを元にして新たなコマンドを作成する +: たとえば、複雑な`search`コマンドをラップして、手軽に使えるコマンドを作りたいかもしれません。 + リクエストとレスポンスに対する*適合(adaption)*がそれを可能にします。 + +新しいコマンドを追加してストレージを操作する +: たとえば、ストレージに保存されているデータを自在に操作したいかもしれません。 + リクエストに対する*ハンドリング(handling)*がそれを可能にします。 + +複雑なタスクを実現するコマンドを追加する +: たとえば、標準の`search`コマンドのような強力なコマンドを実装したいかもしれません。リクエストに対する*立案(planning)*と*収集(collection)*がそれを可能にします。 + +このチュートリアルでは、最初に*適合(adaption)*を扱います。 +これはもっともプラグインの基本的なユースケースなので、Droongaにおけるプラグイン開発の基礎を理解する助けになるはずです。 +その後、他のケースも上述の順で説明します。 +このチュートリアルに従うと、プラグインの書き方を理解できるようになります。 +自分独自の要求を満たすプラグインを作成するための第一歩となることでしょう。 + +## プラグインを開発するには + +詳細は以下のサブチュートリアルを参照してください: + + 1. [リクエストとレスポンスを加工し、既存のコマンドに基づいた新たなコマンドを作成する][adapter]。 + 2. [全てのボリューム上でリクエストを処理し、ストレージを操作する新たなコマンドを追加する][handler]。 + 3. 特定のボリューム上だけでリクエストを処理し、より効率的にストレージを操作するコマンドを追加する (準備中) + 4. リクエストの分散とレスポンスの回収を行い、新たな複雑なコマンドを追加する (準備中) + + + [basic tutorial]: ../basic/ + [overview]: ../../overview/ + [adapter]: ./adapter/ + [handler]: ./handler/ + [distribute-collect]: ./distribute-collect/ Added: ja/tutorial/1.1.2/virtual-machines-for-experiments/index.md (+250 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/virtual-machines-for-experiments/index.md 2015-11-15 23:29:56 +0900 (1ac9a90) @@ -0,0 +1,250 @@ +--- +title: "Droongaチュートリアル: 実験用の仮想マシンを用意する手順" +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/virtual-machines-for-experiments/index.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## チュートリアルのゴール + +実験用に複数(3台)の仮想マシンを用意する手順を学ぶこと。 + +## なぜ仮想マシンが必要なのか? + +Droongaは分散型のデータ処理システムなので、クラスタを構成するには複数の台のコンピュータを用意する必要があります。 +安全のためにも(そしてより良い性能を得るためにも)、Droongaノードにはそれ用のコンピュータを用意することが望ましいです。 + +有効なレプリケーションのためには、2台以上のコンピュータが必要です。 +また、クラスタ構成の管理を試してみるには、3台以上のコンピュータが必要となります。 + +しかしながら、仮に、単に検証や開発をしたい場合でも、複数の仮想マシンのインスタンスをVPSサービスで利用するにはお金がかかります。 +そのような用途では、あなたの手持ちのコンピュータ上でプライベートな仮想マシンを使うのがおすすめです。 + +幸いなことに、[Vagrant][]を使うと仮想マシンを簡単に管理することができます。 +このチュートリアルでは、Vagrantを使って*3台の仮想マシンを用意する手順*を解説します。 + +## ホストマシンを用意する + +まず最初に、仮想マシンのホストとなるPCを用意する必要があります。 +仮想マシンは多くのRAMを要求する場合があるため、ホストマシンにはできれば8GB以上のメモリがあることが望ましいです。 + +多くの場合、メジャーなプラットフォーム向けにはビルド済みのバイナリが使われるため、それほど多くのRAMは必要ではありません。 +しかしながら、仮想マシン上で動作する環境がマイナーなディストリビューションであったり、そのディストリビューションの最新のバージョンであった場合には、その環境向けのビルド済みバイナリが用意されていないことがあり得ます。そのような場合、バイナリは自動的にコンパイルされますが、その際に2GB程度のメモリが要求されます。 +ネイティブ拡張のビルド時に奇妙なエラーに遭遇した場合は、仮想マシンのメモリの割り当て量を増やして再度インストールを行って下さい。 +([このチュートリアルの付録も参照して下さい](#less-size-memory)。) + +## 仮想マシンを用意する手順 + +### VirtualBoxをインストールする + +Vagrantには、仮想マシンを実行するためのバックエンドが必要です。ここでは推奨環境の[VirtualBox][]をインストールすることにします。 +例えば、ホストマシンが[Ubuntu][]で動作するPCなのであれば、VirtualBoxは以下のように`apt`コマンドでインストールできます: + +~~~ +$ sudo apt-get install virtualbox +~~~ + +その他の環境では、[VirtualBoxのWebサイト][VirtualBox]にある手順に従ってVirtualBoxをインストールして下さい。 + +### Vagrantをインストールする + +次に、[Vagrant][]をインストールします。[VagrantのWebサイト][Vagrant]にある手順に従って、Vagrantをインストールして下さい。 +例えば、ホストマシンがx64のUbuntu PCなのであれば、以下の要領です: + +~~~ +$ wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.6.5_x86_64.deb +$ sudo dpkg -i vagrant_1.6.5_x86_64.deb +~~~ + +注意: Ubuntu 14.04では`apt-get install vagrant`でもVagrantをインストールできますが、これは使わないで下さい。この方法でインストールできるVagrantはバージョンが古いため、[Vagrant Cloud][]からboxをインポートできません。 + +### boxの種類を決めて、Vagrantfileを用意する + +[Vagrant Cloud][]のサイトから、実験に使うためのboxを選びます。 +例えば[Ubuntu Trusty (x64)のbox](https://vagrantcloud.com/ubuntu/boxes/trusty64)を使うのであれば、以下のようにします: + +~~~ +$ mkdir droonga-ubuntu-trusty +$ cd droonga-ubuntu-trusty +$ vagrant init ubuntu/trusty64 +~~~ + +この操作で、設定ファイルの`Vagrantfile`が自動生成されます。 +しかし、このファイルはDroongaクラスタの実験のために、以下のように完全に書き換えてしまいます: + +`Vagrantfile`: + +~~~ +n_machines = 3 +box = "ubuntu/trusty64" + +VAGRANTFILE_API_VERSION = "2" +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + n_machines.times do |index| + config.vm.define :"node#{index}" do |node_config| + node_config.vm.box = box + node_config.vm.network(:private_network, + :ip => "192.168.100.#{50 + index}") + node_config.vm.host_name = "node#{index}" + node_config.vm.provider("virtualbox") do |virtual_box| + virtual_box.memory = 2048 + end + end + end +end +~~~ + +注:この`Vagrantfile`では、3つの仮想マシンを2GB(2048MB)のメモリを伴って定義しています。 +ですので、ホストマシンは6GB以上のメモリを搭載している必要があります。 +もしホストマシンのメモリがそこまで多くないのであれば、この時点では`512`(512MB)などの適当な値を設定しておいて下さい。 + +### 仮想マシンを起動する + +仮想マシンは、`vagrant up`というコマンドで起動できます: + +~~~ +$ vagrant up +Bringing machine 'node0' up with 'virtualbox' provider... +Bringing machine 'node1' up with 'virtualbox' provider... +Bringing machine 'node2' up with 'virtualbox' provider... +... +~~~ + +これにより、Vagrantは自動的に仮想マシンのイメージを[Vagrant Cloud][]のWebサイトからダウンロードし、それが終わり次第仮想マシンを起動します。 +用意が完了すると、仮想ネットワーク上のIPアドレスとして`192.168.100.50`、`192.168.100.51`、`192.168.100.52`をそれぞれ持つ3台の仮想マシンが動作している状態になります。 + +仮想マシンが正しく動いていることを確認しましょう。 +仮想マシンには`vagrant ssh`コマンドを使って以下のようにログインできます: + +~~~ +$ vagrant ssh node0 +Welcome to Ubuntu 14.04.1 LTS (GNU/Linux 3.13.0-36-generic x86_64) +... +vagrant �� node0:~$ exit +~~~ + + +### 仮想マシンをSSHクライアントに登録する + +仮想マシンにログインするためには、通常の`ssh`コマンドではなく、`vagrant ssh`コマンドを使わなくてはなりません。 +また、その前には`Vagrantfile`があるディレクトリに`cd`する必要もあります。 +これは少々面倒です。 + +ですので、SSHクライアントのローカル設定ファイルに、以下のようにして仮想マシンのための設定を追加しておきましょう: + +~~~ +$ vagrant ssh-config node0 >> ~/.ssh/config +$ vagrant ssh-config node1 >> ~/.ssh/config +$ vagrant ssh-config node2 >> ~/.ssh/config +~~~ + +これで、`vagrant ssh`コマンドを使わずとも、仮想マシンの名前を指定してログインできるようになります: + +~~~ +$ ssh node0 +~~~ + +### 仮想マシン同士で互いのホスト名を名前解決できるように設定する + +ネームサーバがないので、各仮想マシンはお互いのホスト名を名前解決する事ができません。 +そのため、現時点ではそれぞれのIPアドレスを直接書く必要があります。 +これは非常に面倒です。 + +なので、各仮想マシンのhostsファイルを以下のように編集しておきましょう: + +`/etc/hosts`: + +~~~ +127.0.0.1 localhost +192.168.100.50 node0 +192.168.100.51 node1 +192.168.100.52 node2 +~~~ + +これで、各マシンはお互いにホスト名を指定して通信できるようになります。 + +### 仮想マシンの終了 + +仮想マシンは、`vagrant halt`コマンドでまとめて終了できます: + +~~~ +$ vagrant halt +~~~ + +これで、Vagrantがすべての仮想マシンを完全に終了させてくれます。 + +### 仮想マシンで行った変更を取り消す + +仮想マシンの中で行ったすべての変更を取り消したい場合は、単純に`vagrant destroy -f`というコマンドを実行すればOKです: + +~~~ +$ vagrant destroy -f +$ vagrant up +~~~ + +これで、すべての変更を取り消して、仮想マシンをまっさらの状態で起動し直すことができます。 +この方法はインストールスクリプトの改修などの作業をする時に便利でしょう。 + +### 付録: ホストマシンのRAMがそれほど多くない場合 {#less-size-memory} + +手持ちのコンピュータが十分なサイズのメモリを搭載していないとしても、諦める必要はありません。 + +各仮想マシンに2GBのメモリが必要になるのは、[Rroonga][]のネイティブ拡張をビルドする必要があるからです。 +言い換えると、既にビルド済みのバイナリがあるのであれば、Droongaノードはそこまでのメモリがなくても動作します。 + +ですので、以下のようにすると、各仮想マシンに順番にDroongaのサービスをインストールしていくことができます: + + 1. `vagrant halt`ですべての仮想マシンを終了する。 + 2. `virtualbox`でVirtualBoxのコンソールを開く。 + 3. 1台の仮想マシンのプロパティを開き、メモリの大きさを2GB(2048MB)に設定し直す。 + 4. VirtualBoxのコンソールからその仮想マシンを起動する。 + 5. 仮想マシンにログインし、Droongaのサービスをインストールする。 + 6. 仮想マシンを終了する。 + 7. 仮想マシンのプロパティを開き、メモリの大きさを元に戻す。 + 8. 3から7の手順を他の仮想マシンにも繰り返す。 + +### 付録: 他のコンピュータから仮想マシン上のサービスに直接アクセスする + +ホストマシンが(リモートにある)サーバで、あなたが主に手元の別のPCを操作している状況において、仮想マシン内で動作しているHTTPサーバに手元のPCから直接接続したいと思うことがあるかもしれません。 +例えば、Google Chrome、Mozilla FirefoxのようなWebブラウザを使って管理ページを操作してみたい場合などです。 + +このような場面では、OpenSSHのポートフォワーディング機能を使うと良いでしょう。 +以下のコマンドをホストマシン上で実行してください。 + +~~~ +% ssh vagrant �� 192.168.100.50 \ + -i ~/.vagrant.d/insecure_private_key \ + -g \ + -L 20041:localhost:10041 +~~~ + +これにより、仮想マシン`node0`(`192.168.100.50`)上の`droonga-http-server`が提供している管理ページに、`http://(ホストマシンのIPアドレスまたはホスト名):20041/`というURLで実際にアクセスする事ができます。 +この時、ホストマシン上で動作しているOpenSSHのクライアントによって、`20041`番ポートに流れ込んできたパケットはすべて仮想マシン内の`10041`番ポートに転送されます。 + + * `vagrant@` というユーザ名と認証に使う秘密鍵を指定する必要があるので注意してください。 + * ホストコンピュータ自身の外から来るリクエストを受け付けるためには、`-g`オプションの指定が必要です。 + +## まとめ + +このチュートリアルでは、Droongaノード用に3台の仮想マシンを用意する手順を学びました。 + +これで、[「使ってみる」のチュートリアル](../groonga/)を複数ノードで実践できます。 + + [Vagrant]: https://www.vagrantup.com/ + [Vagrant Cloud]: https://vagrantcloud.com/ + [VirtualBox]: https://www.virtualbox.org/ + [Groonga]: http://groonga.org/ + [Rroonga]: https://github.com/ranguba/rroonga + [Ubuntu]: http://www.ubuntu.com/ + [Droonga]: https://droonga.org/ + [Groonga]: http://groonga.org/ Added: ja/tutorial/1.1.2/watch.md (+217 -0) 100644 =================================================================== --- /dev/null +++ ja/tutorial/1.1.2/watch.md 2015-11-15 23:29:56 +0900 (d4b906f) @@ -0,0 +1,217 @@ +--- +title: Droonga チュートリアル +layout: ja +--- + +{% comment %} +############################################## + THIS FILE IS AUTOMATICALLY GENERATED FROM + "_po/ja/tutorial/1.1.2/watch.po" + DO NOT EDIT THIS FILE MANUALLY! +############################################## +{% endcomment %} + + +* TOC +{:toc} + +## Real-time search + +Droonga supports streaming-style real-time search. + +### Update configurations of the Droonga engine + +Update your fluentd.conf and catalog.jsons, like: + +fluentd.conf: + + <source> + type forward + port 24224 + </source> + <match starbucks.message> + name localhost:24224/starbucks + type droonga + </match> + + <match droonga.message> + + name localhost:24224/droonga + + type droonga + + </match> + <match output.message> + type stdout + </match> + +catalog.json: + + { + "effective_date": "2013-09-01T00:00:00Z", + "zones": [ + + "localhost:24224/droonga", + "localhost:24224/starbucks" + ], + "farms": { + + "localhost:24224/droonga": { + + "device": ".", + + "capacity": 10 + + }, + "localhost:24224/starbucks": { + "device": ".", + "capacity": 10 + } + }, + "datasets": { + + "Watch": { + + "workers": 2, + + "plugins": ["search", "groonga", "add", "watch"], + + "number_of_replicas": 1, + + "number_of_partitions": 1, + + "partition_key": "_key", + + "date_range": "infinity", + + "ring": { + + "localhost:23041": { + + "weight": 50, + + "partitions": { + + "2013-09-01": [ + + "localhost:24224/droonga.watch" + + ] + + } + + } + + } + + }, + "Starbucks": { + "workers": 0, + "plugins": ["search", "groonga", "add"], + "number_of_replicas": 2, + "number_of_partitions": 2, + "partition_key": "_key", + "date_range": "infinity", + "ring": { + "localhost:23041": { + "weight": 50, + "partitions": { + "2013-09-01": [ + "localhost:24224/starbucks.000", + "localhost:24224/starbucks.001" + ] + } + }, + "localhost:23042": { + "weight": 50, + "partitions": { + "2013-09-01": [ + "localhost:24224/starbucks.002", + "localhost:24224/starbucks.003" + ] + } + } + } + } + }, + "options": { + "plugins": [] + } + } + +### Add a streaming API to the protocol adapter + + +Add a streaming API to the protocol adapter, like; + +application.js: + + var express = require('express'), + droonga = require('express-droonga'); + + var application = express(); + var server = require('http').createServer(application); + server.listen(3000); // the port to communicate with clients + + //============== INSERTED ============== + var streaming = { + 'streaming': new droonga.command.HTTPStreaming({ + dataset: 'Watch', + path: '/watch', + method: 'GET', + subscription: 'watch.subscribe', + unsubscription: 'watch.unsubscribe', + notification: 'watch.notification', + createSubscription: function(request) { + return { + condition: request.query.query + }; + } + }) + }; + //============= /INSERTED ============== + + application.droonga({ + prefix: '/droonga', + tag: 'starbucks', + defaultDataset: 'Starbucks', + server: server, // this is required to initialize Socket.IO API! + plugins: [ + droonga.API_REST, + droonga.API_SOCKET_IO, + droonga.API_GROONGA, + droonga.API_DROONGA + //============== INSERTED ============== + ,streaming + //============= /INSERTED ============== + ] + }); + + application.get('/', function(req, res) { + res.sendfile(__dirname + '/index.html'); + }); + +### Prepare feeds + +Prepare "feed"s like: + +feeds.jsons: + + {"id":"feed:0","dataset":"Watch","type":"watch.feed","body":{"targets":{"key":"old place 0"}}} + {"id":"feed:1","dataset":"Watch","type":"watch.feed","body":{"targets":{"key":"new place 0"}}} + {"id":"feed:2","dataset":"Watch","type":"watch.feed","body":{"targets":{"key":"old place 1"}}} + {"id":"feed:3","dataset":"Watch","type":"watch.feed","body":{"targets":{"key":"new place 1"}}} + {"id":"feed:4","dataset":"Watch","type":"watch.feed","body":{"targets":{"key":"old place 2"}}} + {"id":"feed:5","dataset":"Watch","type":"watch.feed","body":{"targets":{"key":"new place 2"}}} + +### Try it! + +At first, restart servers in each console. + +The engine: + + # fluentd --config fluentd.conf + +The protocol adapter: + + # nodejs application.js + +Next, connect to the streaming API via curl: + + # curl "http://localhost:3000/droonga/watch?query=new" + +Then the client starts to receive streamed results. + +Next, open a new console and send "feed"s to the engine like: + + # fluent-cat droonga.message < feeds.jsons + +Then the client receives three results "new place 0", "new place 1", and "new place 2" like: + + {"targets":{"key":"new place 0"}} + {"targets":{"key":"new place 1"}} + {"targets":{"key":"new place 2"}} + +They are search results for the query "new", given as a query parameter of the streaming API. + +Results can be appear in different order, like: + + {"targets":{"key":"new place 1"}} + {"targets":{"key":"new place 0"}} + {"targets":{"key":"new place 2"}} + +because "feed"s are processed in multiple workers asynchronously. +