From 1b6d1488ff733a0890b25141141060c077f6a907 Mon Sep 17 00:00:00 2001 From: "min.wu" <50101159+whitewum@users.noreply.github.com> Date: Thu, 26 Aug 2021 17:00:07 +0800 Subject: [PATCH] Mergev250 (#910) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update deploy.yaml * Update deploy.yaml * Delete header.html * fix-brokenlink * Update mkdocs.yml * Update README.md * Update README.md * Update 2.install-nebula-graph-by-rpm-or-deb.md * Update 4.date-and-time.md * Update mkdocs.yml * Update requirements.txt * Update 2.install-nebula-graph-by-rpm-or-deb.md * Update show hosts results (#882) * Update 6.list.md * Update 2.1.path.md * Update 2.user-defined-variables.md * Update 4.pipe.md * Update 6.set.md * Update 7.string.md * Update 8.list.md * Update requirements.txt * Update 3.date-and-time.md * Update 6.list.md * update (#884) * Update 3.upsert-edge.md * update (#885) * Update 2.match.md * Update 8.show-indexes.md (#883) * Update 1.resource-preparations.md * Update mkdocs.yml * merge * add release notes * Update requirements.txt * update (#887) * add console commands (#888) * Update 1.authentication.md * Update 1.what-is-nebula-graph.md * Update 2.data-model.md * Update 1.architecture-overview.md * Update 2.install-nebula-graph-by-rpm-or-deb.md * Update 3.deploy-nebula-graph-with-docker-compose.md * Update 4.nebula-graph-crud.md * Update 4.nebula-graph-crud.md * Update 2.user-defined-variables.md * update * Update 4.nebula-graph-crud.md * Update 4.nebula-graph-crud.md * Update 1.overview.md * Update 3.graph-patterns.md * Update 1.install-nebula-graph-by-compiling-the-source-code.md * Update 3.graph-patterns.md * Update ngql-style-guide.md * Update releasenote.md * Update ngql-style-guide.md * Update 4.date-and-time.md * Update ngql-style-guide.md * Update 1.composite-queries.md * Modify doc (#889) * add console commands * update * Update 1.overview.md * Update 1.overview.md * Update 1.composite-queries.md * Update 4.date-and-time.md * Update 4.job-statements.md * Update 4.br-restore-data.md * Update README.md * Update README.md * Update mkdocs.yml * Update ex-ug-import-from-kafka.md (#890) * Update st-ug-deploy.md * Update 2.deploy-dashboard.md * Update 4.storage-config.md * Update st-ug-deploy.md * Update 1.get-subgraph.md (#891) * Update 2.deploy-dashboard.md * Update 2.deploy-dashboard.md * Update nebula-algorithm.md * Update 2.install-nebula-graph-by-rpm-or-deb.md * Update ex-ug-parameter.md * update (#892) * Create 2.deploy-dashboard.md * Update st-ug-deploy.md * Update 3.br-backup-data.md * Update source_connect-to-nebula-graph.md * Update source_connect-to-nebula-graph.md * Update 2.find-path.md * Clarify index selection behavior * Update 1.overview.md * String writing operations (#894) * about string writing operations * Update 3.string.md * Update mkdocs.yml (#895) * Update 6.eco-tool-version.md (#896) * Update 2.install-nebula-graph-by-rpm-or-deb.md * Update mind-map.md * Update 1.resource-preparations.md * Update 2.deploy-dashboard.md * Update 6.eco-tool-version.md (#897) * Update 1.resource-preparations.md * Add compatibility note for index selection (#898) * Delete header.html * Update 2.install-nebula-graph-by-rpm-or-deb.md * list supported property types (#901) * Update 2.install-nebula-graph-by-rpm-or-deb.md * Update mkdocs.yml * Update 6.eco-tool-version.md * Update 6.eco-tool-version.md (#902) * Update releasenote.md (#903) * Update releasenote.md * Update 4.nebula-graph-crud.md * Update 1.install-nebula-graph-by-compiling-the-source-code.md * Update 6.eco-tool-version.md * Update README.md * Update 2.deploy-dashboard.md * Update 1.install-nebula-graph-by-compiling-the-source-code.md * Update 2.deploy-dashboard.md * Update 2.deploy-dashboard.md * Update 2.deploy-dashboard.md * Update 2.install-nebula-graph-by-rpm-or-deb.md * Specify the path when installing, then you also need to specify the path when upgrading Specify the path when installing, then you also need to specify the path when upgrading。 * It is recommended to back up the configuration file before updating (#905) It is recommended to back up the configuration file before updating * Update 1.install-nebula-graph-by-compiling-the-source-code.md * Update 3.deploy-nebula-graph-with-docker-compose.md * Update 3.deploy-nebula-graph-with-docker-compose.md * Update ex-ug-deploy.md * Update return.md * Update st-ug-deploy.md * Update return.md * Update 4.nebula-graph-crud.md * Update 1.overview.md * Update order-by.md * Update 2.match.md * Update 1.composite-queries.md * update (#906) * Update source_manage-service.md * Optimize the reuse method and resolve some issues (#907) * Fix format issues (#908) * Update st-ug-what-is-graph-studio.md * Update st-ug-what-is-graph-studio.md * Update st-ug-what-is-graph-studio.md * Update st-ug-what-is-graph-studio.md * Update st-ug-what-is-graph-studio.md * Update st-ug-deploy.md * Update 1.what-is-nebula-graph.md * Update 3.role-list.md (#909) * Update 2.management-user.md * Update 3.go.md * Update 3.property-reference.md Co-authored-by: foesa <35463247+foesa-yang@users.noreply.github.com> Co-authored-by: cooper-lzy <78672629+cooper-lzy@users.noreply.github.com> Co-authored-by: randomJoe211 <69501902+randomJoe211@users.noreply.github.com> Co-authored-by: Nut He <18328704+hetao92@users.noreply.github.com> Co-authored-by: Sophie-Xie <84560950+Sophie-Xie@users.noreply.github.com> Co-authored-by: li Nico <37568394+NicolaCage@users.noreply.github.com> Co-authored-by: study-day <38400198+study-day@users.noreply.github.com> --- .github/workflows/deploy.yaml | 11 +- .../1.introduction/1.what-is-nebula-graph.md | 4 +- docs-2.0/1.introduction/2.1.path.md | 2 +- docs-2.0/1.introduction/2.data-model.md | 6 +- .../1.architecture-overview.md | 6 +- .../4.storage-service.md | 2 +- .../2.quick-start/2.install-nebula-graph.md | 4 + .../3.connect-to-nebula-graph.md | 5 +- docs-2.0/2.quick-start/4.nebula-graph-crud.md | 50 ++--- .../2.quick-start/5.start-stop-service.md | 5 +- docs-2.0/20.appendix/0.FAQ.md | 8 +- docs-2.0/20.appendix/6.eco-tool-version.md | 70 +++---- docs-2.0/20.appendix/mind-map.md | 6 +- docs-2.0/20.appendix/releasenote.md | 71 +++++++ .../1.nGQL-overview/1.overview.md | 21 +- .../1.nGQL-overview/3.graph-patterns.md | 4 +- .../1.nGQL-overview/ngql-style-guide.md | 14 ++ .../10.tag-statements/1.create-tag.md | 2 +- .../11.edge-type-statements/1.create-edge.md | 2 +- .../13.edge-statements/3.upsert-edge.md | 2 +- .../1.create-native-index.md | 20 +- .../16.subgraph-and-path/1.get-subgraph.md | 44 ++--- .../16.subgraph-and-path/2.find-path.md | 6 +- .../4.job-statements.md | 4 +- .../3.ngql-guide/3.data-types/3.string.md | 5 +- .../3.data-types/4.date-and-time.md | 10 +- docs-2.0/3.ngql-guide/3.data-types/6.list.md | 2 +- .../1.composite-queries.md | 7 +- .../2.user-defined-variables.md | 6 +- .../3.property-reference.md | 6 +- docs-2.0/3.ngql-guide/5.operators/4.pipe.md | 4 +- docs-2.0/3.ngql-guide/5.operators/6.set.md | 8 +- docs-2.0/3.ngql-guide/5.operators/7.string.md | 12 +- docs-2.0/3.ngql-guide/5.operators/8.list.md | 2 +- .../3.date-and-time.md | 4 +- .../6.functions-and-expressions/6.list.md | 2 +- .../6.functions-and-expressions/7.count.md | 2 +- .../7.general-query-statements/2.match.md | 16 +- .../7.general-query-statements/3.go.md | 2 +- .../7.general-query-statements/5.lookup.md | 83 ++++---- .../6.show/6.show-hosts.md | 54 ++--- .../6.show/8.show-indexes.md | 35 ++-- .../8.clauses-and-options/limit.md | 2 +- .../8.clauses-and-options/order-by.md | 8 +- .../8.clauses-and-options/return.md | 20 ++ .../8.clauses-and-options/where.md | 2 +- .../1.resource-preparations.md | 10 +- ...bula-graph-by-compiling-the-source-code.md | 8 +- .../2.install-nebula-graph-by-rpm-or-deb.md | 134 +------------ ...deploy-nebula-graph-with-docker-compose.md | 12 +- .../upgrade-nebula-from-200-to-250.md | 11 +- .../upgrade-nebula-graph-to-250.md | 4 +- .../connect-to-nebula-graph.md | 4 + .../manage-service.md | 3 +- .../1.configurations/4.storage-config.md | 2 +- .../1.authentication/1.authentication.md | 6 +- .../1.authentication/2.management-user.md | 23 ++- .../1.authentication/3.role-list.md | 4 +- .../2.backup-restore/3.br-backup-data.md | 1 + .../2.backup-restore/4.br-restore-data.md | 4 +- docs-2.0/8.service-tuning/compaction.md | 10 +- docs-2.0/README.md | 14 +- docs-2.0/nebula-algorithm.md | 10 +- .../nebula-dashboard/2.deploy-dashboard.md | 82 ++++---- .../about-exchange/ex-ug-limitations.md | 1 + .../parameter-reference/ex-ug-parameter.md | 45 ++++- .../use-exchange/ex-ug-import-from-kafka.md | 14 +- .../use-exchange/ex-ug-import-from-sst.md | 14 +- .../deploy-connect/ex-ug-deploy.md | 6 +- docs-2.0/nebula-spark-connector.md | 10 +- .../st-ug-what-is-graph-studio.md | 10 +- .../deploy-connect/st-ug-deploy.md | 13 +- docs-2.0/reuse/assets.png | Bin 0 -> 60450 bytes docs-2.0/reuse/console.png | Bin 0 -> 79795 bytes .../reuse/source_connect-to-nebula-graph.md | 131 ++++++++++-- ...urce_install-nebula-graph-by-rpm-or-deb.md | 130 ++++++++++++ docs-2.0/reuse/source_manage-service.md | 4 +- mkdocs.yml | 23 ++- overrides/partials/header.html | 186 +++++++++--------- 79 files changed, 956 insertions(+), 634 deletions(-) create mode 100644 docs-2.0/2.quick-start/2.install-nebula-graph.md create mode 100644 docs-2.0/20.appendix/releasenote.md create mode 100644 docs-2.0/4.deployment-and-installation/connect-to-nebula-graph.md create mode 100644 docs-2.0/reuse/assets.png create mode 100644 docs-2.0/reuse/console.png create mode 100644 docs-2.0/reuse/source_install-nebula-graph-by-rpm-or-deb.md diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml index 69124f864bd..e4d29881505 100644 --- a/.github/workflows/deploy.yaml +++ b/.github/workflows/deploy.yaml @@ -6,7 +6,7 @@ on: jobs: deploy: - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 with: @@ -15,19 +15,17 @@ jobs: - name: Setup Python uses: actions/setup-python@v1 with: - python-version: '3.7' + python-version: '3.8' architecture: 'x64' - name: apt install run: | sudo apt update -y sudo apt install -y $(cat pkglist.txt) - - name: Install dependencies run: | pip install --upgrade pip pip install -r ./requirements.txt - - name: set LANG run: sh lang-zh.sh @@ -37,17 +35,14 @@ jobs: - name: mike list delete run: | mike list - - name: Mike Deploy master run: | mike deploy master -p --rebase mike list - - name: show git branch run: | git branch git checkout gh-pages - - name: Compress run: | tar -vczf nebula-docs.tar.gz master versions.json *.html @@ -79,4 +74,4 @@ jobs: # uses: peaceiris/actions-gh-pages@v3 # with: # github_token: ${{ secrets.DEPLOY_TOKEN }} - # publish_dir: ./site + # publish_dir: ./site \ No newline at end of file diff --git a/docs-2.0/1.introduction/1.what-is-nebula-graph.md b/docs-2.0/1.introduction/1.what-is-nebula-graph.md index a34059a87f2..28ce865becb 100644 --- a/docs-2.0/1.introduction/1.what-is-nebula-graph.md +++ b/docs-2.0/1.introduction/1.what-is-nebula-graph.md @@ -38,13 +38,13 @@ Nebula Graph支持严格的角色访问控制和LDAP(Lightweight Directory Acc ### 生态多样化 -Nebula Graph开放了越来越多的原生工具,例如[Nebula Graph Studio](https://github.com/vesoft-inc/nebula-web-docker)、[Nebula Console](https://github.com/vesoft-inc/nebula-console)、[Nebula Exchange](https://github.com/vesoft-inc/nebula-spark-utils/tree/v2.0.0/nebula-exchange)等。 +Nebula Graph开放了越来越多的原生工具,例如[Nebula Graph Studio](https://github.com/vesoft-inc/nebula-studio)、[Nebula Console](https://github.com/vesoft-inc/nebula-console)、[Nebula Exchange](https://github.com/vesoft-inc/nebula-spark-utils/tree/v2.0.0/nebula-exchange)等。 此外,Nebula Graph还具备与Spark、Flink、HBase等产品整合的能力,在这个充满挑战与机遇的时代,大大增强了自身的竞争力。 ### 兼容openCypher查询语言 -Nebula Graph查询语言,也称为nGQL,是一种声明性的、兼容openCypher的文本查询语言,易于理解和使用。详细语法请参见[nGQL指南](../3.ngql-guide/1.nGQL-overview/1.overview.md)。 +Nebula Graph 查询语言,简称为 nGQL,是一种声明性的、部分兼容 openCypher 的文本查询语言,易于理解和使用。详细语法请参见[nGQL指南](../3.ngql-guide/1.nGQL-overview/1.overview.md)。 ### 面向未来硬件,读写平衡 diff --git a/docs-2.0/1.introduction/2.1.path.md b/docs-2.0/1.introduction/2.1.path.md index 2699556cba4..64966cac2fe 100644 --- a/docs-2.0/1.introduction/2.1.path.md +++ b/docs-2.0/1.introduction/2.1.path.md @@ -48,7 +48,7 @@ ## 视频 -用户也可以观看视频了解Path的相关概念。 +用户也可以观看视频了解路径的相关概念。 [Nebula Algorithm](https://www.bilibili.com/video/BV1Uf4y1t72L)(03分09秒) diff --git a/docs-2.0/1.introduction/2.data-model.md b/docs-2.0/1.introduction/2.data-model.md index 616822a0c6a..a84bc961318 100644 --- a/docs-2.0/1.introduction/2.data-model.md +++ b/docs-2.0/1.introduction/2.data-model.md @@ -1,10 +1,10 @@ # 数据模型 -本文介绍Nebula Graph的数据模型。数据模型是一种组织数据并说明它们如何相互关联的模型。 +本文介绍Nebula Graph的数据模型。数据模型是一种组织数据并说明它们如何相互关联的模型(schema)。 -## 数据结构 +## 数据模型 -Nebula Graph数据模型使用6种基本的数据结构: +Nebula Graph数据模型使用6种基本的数据模型: - 图空间(Space) diff --git a/docs-2.0/1.introduction/3.nebula-graph-architecture/1.architecture-overview.md b/docs-2.0/1.introduction/3.nebula-graph-architecture/1.architecture-overview.md index a6ead9669ec..1f031019350 100644 --- a/docs-2.0/1.introduction/3.nebula-graph-architecture/1.architecture-overview.md +++ b/docs-2.0/1.introduction/3.nebula-graph-architecture/1.architecture-overview.md @@ -1,4 +1,4 @@ -# 架构总览 +# Nebula Graph 架构总览 Nebula Graph 由三种服务构成:Graph 服务、Meta 服务和 Storage 服务,是一种存储与计算分离的架构。 @@ -28,7 +28,9 @@ Nebula Graph 采用计算存储分离架构。Graph 服务负责处理计算请 - 节约成本 - 计算存储分离架构能够提高资源利用率,而且可根据业务需求灵活控制成本。如果使用 [Nebula Graph Cloud](https://cloud.nebula-graph.com.cn/ "Nebula Graph Cloud official website"),可以进一步节约前期成本。 + 计算存储分离架构能够提高资源利用率,而且可根据业务需求灵活控制成本。 + + - 更多可能性 diff --git a/docs-2.0/1.introduction/3.nebula-graph-architecture/4.storage-service.md b/docs-2.0/1.introduction/3.nebula-graph-architecture/4.storage-service.md index 87c4b79d051..a670b248774 100644 --- a/docs-2.0/1.introduction/3.nebula-graph-architecture/4.storage-service.md +++ b/docs-2.0/1.introduction/3.nebula-graph-architecture/4.storage-service.md @@ -38,7 +38,7 @@ Storage服务是由nebula-storaged进程提供的,用户可以根据场景配 - Consensus层 - Storage服务的中间层,实现了[Multi Group Raft](#raft协议),保证强一致性和高可用性。 + Storage服务的中间层,实现了[Multi Group Raft](#multi_group_raft),保证强一致性和高可用性。 - Store Engine层 diff --git a/docs-2.0/2.quick-start/2.install-nebula-graph.md b/docs-2.0/2.quick-start/2.install-nebula-graph.md new file mode 100644 index 00000000000..ce99db09ed1 --- /dev/null +++ b/docs-2.0/2.quick-start/2.install-nebula-graph.md @@ -0,0 +1,4 @@ +# 步骤1:安装Nebula Graph + +{% include "/source_install-nebula-graph-by-rpm-or-deb.md" %} + diff --git a/docs-2.0/2.quick-start/3.connect-to-nebula-graph.md b/docs-2.0/2.quick-start/3.connect-to-nebula-graph.md index 63374679591..a188805977c 100644 --- a/docs-2.0/2.quick-start/3.connect-to-nebula-graph.md +++ b/docs-2.0/2.quick-start/3.connect-to-nebula-graph.md @@ -1,5 +1,4 @@ # 步骤3:连接Nebula Graph ---8<-- "source_connect-to-nebula-graph.md" - - \ No newline at end of file +{% include "/source_connect-to-nebula-graph.md" %} + diff --git a/docs-2.0/2.quick-start/4.nebula-graph-crud.md b/docs-2.0/2.quick-start/4.nebula-graph-crud.md index c7eb656b15f..e095e26960e 100644 --- a/docs-2.0/2.quick-start/4.nebula-graph-crud.md +++ b/docs-2.0/2.quick-start/4.nebula-graph-crud.md @@ -27,7 +27,9 @@ ## 检查Nebula Graph集群的机器状态 -首先建议检查机器状态,确保所有的Storage服务连接到了Meta服务。执行命令`SHOW HOSTS`查看机器状态。 +!!! Note + + 首先建议检查机器状态,确保所有的Storage服务连接到了Meta服务。执行命令`SHOW HOSTS`查看机器状态。 ```ngql nebula> SHOW HOSTS; @@ -49,7 +51,9 @@ Got 4 rows (time spent 1061/2251 us) ### 异步实现创建和修改 -Nebula Graph中执行如下创建和修改操作,是异步实现的,需要在下一个心跳周期才同步数据。 +!!! caution + + Nebula Graph中执行如下创建和修改操作,是异步实现的。要在**下一个**心跳周期之后才能生效;否则访问会报错。 - `CREATE SPACE` - `CREATE TAG` @@ -165,7 +169,7 @@ CREATE {TAG | EDGE} { | }( ### 示例 -创建Tag`player`和`team`,以及Edge type`follow`和`serve`。说明如下表。 +创建Tag:`player`和`team`,以及Edge type:`follow`和`serve`。说明如下表。 | 名称 | 类型 | 属性 | | :--- | :--- | :--- | @@ -178,22 +182,14 @@ CREATE {TAG | EDGE} { | }( nebula> CREATE TAG player(name string, age int); Execution succeeded (time spent 20708/22071 us) -Wed, 24 Feb 2021 03:47:01 EST - nebula> CREATE TAG team(name string); Execution succeeded (time spent 5643/6810 us) -Wed, 24 Feb 2021 03:47:59 EST - nebula> CREATE EDGE follow(degree int); Execution succeeded (time spent 12665/13934 us) -Wed, 24 Feb 2021 03:48:07 EST - nebula> CREATE EDGE serve(start_year int, end_year int); Execution succeeded (time spent 5858/6870 us) - -Wed, 24 Feb 2021 03:48:16 EST ``` ## 插入点和边 @@ -231,22 +227,14 @@ Wed, 24 Feb 2021 03:48:16 EST nebula> INSERT VERTEX player(name, age) VALUES "player100":("Tim Duncan", 42); Execution succeeded (time spent 28196/30896 us) - Wed, 24 Feb 2021 03:55:08 EST - nebula> INSERT VERTEX player(name, age) VALUES "player101":("Tony Parker", 36); Execution succeeded (time spent 2708/3834 us) - Wed, 24 Feb 2021 03:55:20 EST - nebula> INSERT VERTEX player(name, age) VALUES "player102":("LaMarcus Aldridge", 33); Execution succeeded (time spent 1945/3294 us) - Wed, 24 Feb 2021 03:55:32 EST - nebula> INSERT VERTEX team(name) VALUES "team200":("Warriors"), "team201":("Nuggets"); Execution succeeded (time spent 2269/3310 us) - - Wed, 24 Feb 2021 03:55:47 EST ``` - 插入代表球员和球队之间关系的边。 @@ -255,22 +243,14 @@ Wed, 24 Feb 2021 03:48:16 EST nebula> INSERT EDGE follow(degree) VALUES "player100" -> "player101":(95); Execution succeeded (time spent 3362/4542 us) - Wed, 24 Feb 2021 03:57:36 EST - nebula> INSERT EDGE follow(degree) VALUES "player100" -> "player102":(90); Execution succeeded (time spent 2974/4274 us) - Wed, 24 Feb 2021 03:57:44 EST - nebula> INSERT EDGE follow(degree) VALUES "player102" -> "player101":(75); Execution succeeded (time spent 1891/3096 us) - Wed, 24 Feb 2021 03:57:52 EST - nebula> INSERT EDGE serve(start_year, end_year) VALUES "player100" -> "team200":(1997, 2016), "player101" -> "team201":(1999, 2018); Execution succeeded (time spent 6064/7104 us) - - Wed, 24 Feb 2021 03:58:01 EST ``` ## 查询数据 @@ -279,9 +259,9 @@ Wed, 24 Feb 2021 03:48:16 EST - [FETCH](../3.ngql-guide/7.general-query-statements/4.fetch.md)语句可以获得点或边的属性。 -- [LOOKUP](../3.ngql-guide/7.general-query-statements/5.lookup.md)语句是基于[索引](#_14)的,和`WHERE`子句一起使用,查找符合特定条件的数据。 +- [LOOKUP](../3.ngql-guide/7.general-query-statements/5.lookup.md)语句是基于[索引](#_12)的,和`WHERE`子句一起使用,查找符合特定条件的数据。 -- [MATCH](../3ngql-guide/../3.ngql-guide/7.general-query-statements/2.match.md)语句是查询图数据最常用的,但是它依赖[索引](#_14)去匹配Nebula Graph中的数据模型。 +- [MATCH](../3ngql-guide/../3.ngql-guide/7.general-query-statements/2.match.md)语句是查询图数据最常用的,可以灵活的描述各种图模式,但是它依赖[索引](#_12)去匹配Nebula Graph中的数据模型,性能也还需要调优。 ### nGQL语法 @@ -416,7 +396,7 @@ Got 1 rows (time spent 2006/2406 us) !!! Note - `LOOKUP`和`MATCH`的示例在下文的[索引](#_14)部分查看。 + `LOOKUP`和`MATCH`的示例在下文的[索引](#_12)部分查看。 ## 修改点和边 @@ -426,7 +406,7 @@ Got 1 rows (time spent 2006/2406 us) !!! Note - `UPSERT`操作是基于Nebula Graph的分区进行串行操作,所以执行速度比单独执行`INSERT`或`UPDATE`慢。 + 每个 partition 内部,`UPSERT` 操作是一个串行操作,所以执行速度比执行 `INSERT` 或 `UPDATE` 慢很多。其仅在多个 partition 之间有并发。 ### nGQL语法 @@ -459,8 +439,6 @@ Got 1 rows (time spent 2006/2406 us) nebula> UPDATE VERTEX "player100" SET player.name = "Tim"; Execution succeeded (time spent 3483/3914 us) - Wed, 21 Oct 2020 10:53:14 UTC - nebula> FETCH PROP ON player "player100"; +---------------------------------------------+ | vertices_ | @@ -541,11 +519,11 @@ Got 1 rows (time spent 2006/2406 us) 用户可以通过[CREATE INDEX](../3.ngql-guide/14.native-index-statements/1.create-native-index.md)语句为Tag和Edge type增加索引。 -### 使用索引必读 +!!! caution "使用索引必读" -- `MATCH`和`LOOKUP`语句的执行都依赖索引,但是索引会导致写性能大幅降低(降低90%甚至更多)。请**不要随意**在生产环境中使用索引,除非很清楚使用索引对业务的影响。 + `MATCH`和`LOOKUP`语句的执行都依赖索引,但是索引会导致写性能大幅降低(降低90%甚至更多)。请**不要随意**在生产环境中使用索引,除非很清楚使用索引对业务的影响。 -- **必须**为已存在的数据重建索引,否则不能索引已存在的数据,导致无法在`MATCH`和`LOOKUP`语句中返回这些数据。更多信息,请参见[重建索引](../3.ngql-guide/14.native-index-statements/1.create-native-index.md)。 + **必须**为“已写入但未构建索引”的数据重建索引,否则无法在`MATCH`和`LOOKUP`语句中返回这些数据。参见[重建索引](../3.ngql-guide/14.native-index-statements/4.rebuild-native-index.md)。 ### nGQL语法 diff --git a/docs-2.0/2.quick-start/5.start-stop-service.md b/docs-2.0/2.quick-start/5.start-stop-service.md index c4c11402ffb..cc92637d43a 100644 --- a/docs-2.0/2.quick-start/5.start-stop-service.md +++ b/docs-2.0/2.quick-start/5.start-stop-service.md @@ -1,5 +1,4 @@ # 步骤2:启动Nebula Graph服务 ---8<-- "source_manage-service.md" - - \ No newline at end of file +{% include "/source_manage-service.md" %} + diff --git a/docs-2.0/20.appendix/0.FAQ.md b/docs-2.0/20.appendix/0.FAQ.md index 6173034d017..1a3bec18e0a 100644 --- a/docs-2.0/20.appendix/0.FAQ.md +++ b/docs-2.0/20.appendix/0.FAQ.md @@ -23,7 +23,7 @@ Nebula Graph一直在持续开发,功能或操作的行为可能会有变化 !!! compatibility "`X`版本兼容性" Nebula Graph {{ nebula.release }} 与 历史版本 (包括 Nebula Graph 1.x 和 2.0-RC) 的数据格式、客户端通信协议均**双向不兼容**。 - 数据格式升级参见[升级 Nebula Graph 历史版本至 v2.0.0](../4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-200.md)。 + 数据格式升级参见[升级 Nebula Graph 历史版本至 v2.0.0](../4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-250.md)。 客户端与工具均需要[下载对应版本](../20.appendix/6.eco-tool-version.md)。 !!! compatibility "`Y`版本兼容性" @@ -145,7 +145,8 @@ Storage服务在毫秒级时间内多次收到插入或者更新同一点或边 报错原因通常为Graph服务向Storage服务请求了过多的数据,导致Storage服务超时。请尝试以下解决方案: -* [修改配置文件](../5.configurations-and-logs/1.configurations/3.graph-config.md): 在`nebula-graphd.conf`文件中修改`--storage_client_timeout_ms`参数的值,以增加Storage client的连接超时时间。该值的单位为毫秒(ms)。例如,设置`--storage_client_timeout_ms=60000`。如果`nebula-graphd.conf`文件中未配置该参数,请手动增加。提示:请在配置文件开头添加--local_config=true再重启服务。 +* [修改配置文件](../5.configurations-and-logs/1.configurations/3.graph-config.md): 在`nebula-graphd.conf`文件中修改`--storage_client_timeout_ms`参数的值,以增加Storage client的连接超时时间。该值的单位为毫秒(ms)。例如,设置`--storage_client_timeout_ms=60000`。如果`nebula-graphd.conf`文件中未配置该参数,请手动增加。 + * 优化查询语句:减少全库扫描型的查询,无论是否用`LIMIT`限制了返回结果的数量;用 GO 语句改写 MATCH 语句(前者有优化,后者无优化)。 * 检查Storaged是否发生的 OOM。(`dmesg |grep nebula`)。 * 为 Storage 服务器提供性能更好的SSD或者内存。 @@ -171,7 +172,8 @@ Storage服务在毫秒级时间内多次收到插入或者更新同一点或边 - 导入数据时,手动[compaction](../8.service-tuning/compaction.md),加速读的速度。 -- 增加Graph服务与Storage服务的RPC连接超时时间,在`nebula-storaged.conf`文件里面修改`--storage_client_timeout_ms`参数的值。该值的单位为毫秒(ms),默认值为60000毫秒。提示:请在配置文件开头添加--local_config=true再重启服务。 +- 增加Graph服务与Storage服务的RPC连接超时时间,在`nebula-storaged.conf`文件里面修改`--storage_client_timeout_ms`参数的值。该值的单位为毫秒(ms),默认值为60000毫秒。 + ### 如何处理`nebula-storaged.INFO`错误日志`MetaClient.cpp:65] Heartbeat failed, status:Wrong cluster!`或者 `nebula-metad.INFO`含有错误日志`HBProcessor.cpp:54] Reject wrong cluster host "x.x.x.x":9771!` diff --git a/docs-2.0/20.appendix/6.eco-tool-version.md b/docs-2.0/20.appendix/6.eco-tool-version.md index 06401219d7b..f79e501220e 100644 --- a/docs-2.0/20.appendix/6.eco-tool-version.md +++ b/docs-2.0/20.appendix/6.eco-tool-version.md @@ -1,9 +1,8 @@ # 生态工具概览 - ![Nebula Graph 鸟瞰图](../1.introduction/nebula-birdview.png) -!!! compatibility +!!! compatibility 内核版本号命名规则为 `X.Y.Z`,表示`大版本X`,`中版本Y`,`小版本Z`。对于客户端的升级要求为: @@ -22,13 +21,11 @@ - 文件命名中含有`RC`表示仅用于预览的非正式版本(`Release Candidate`),其维护周期仅至下个RC或者正式版本发布,其客户端、数据兼容性等均无保证。 - 文件命名中含有`nightly`、`SNAPSHOT`或者日期的为日常开发版本,无质量保证和维护周期。 - + !!! compatibility 1.x版本的生态工具完全不支持在Nebula Graph 2.x版本中使用。 -TODO: Nebula eco tools are not released/packed with kernel. To be updated. - ## Nebula Graph Studio Nebula Graph Studio(简称 Studio)是一款可以通过Web访问的图数据库可视化工具,搭配Nebula Graph DBMS使用,提供构图、数据导入、编写nGQL查询、图探索等一站式服务。详情请参见[什么是Nebula Graph Studio](../nebula-studio/about-studio/st-ug-what-is-graph-studio.md)。 @@ -37,65 +34,65 @@ Nebula Graph Studio(简称 Studio)是一款可以通过Web访问的图数据 Studio 版本发布节奏独立于 Nebula Graph 内核,其命名方式也不参照内核命名规则,两者兼容对应关系如下表。 -|Nebula Graph版本|Studio版本| +|Nebula Graph版本|Studio版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{studio.base300}} | +| {{ nebula.release }} | {{studio.base300}}(9e2a120)| ## Nebula Graph Dashboard Nebula Graph Dashboard(简称Dashboard)是一款用于监控Nebula Graph集群中机器和服务状态的可视化工具。详情参见[什么是Nebula Graph Dashboard](../nebula-dashboard/1.what-is-dashboard.md)。 -|Nebula Graph版本|Dashboard版本| +|Nebula Graph版本|Dashboard版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{dashboard.release}} | +| {{ nebula.release }} | {{dashboard.release}}(2b91b3c) | ## Nebula Graph Explorer Nebula Graph Explorer(简称 Explorer)是一款可以通过 Web 访问的图探索可视化工具,搭配 Nebula Graph 内核使用,用于与图数据进行可视化交互。即使没有图数据操作经验,用户也可以快速成为图专家。详情参见[什么是Nebula Graph Explorer](../nebula-explorer/about-explorer/ex-ug-what-is-explorer.md)。 -|Nebula Graph版本|Explorer版本| +|Nebula Graph版本|Explorer版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{explorer.base100}} | +| {{ nebula.release }} | {{explorer.base100}}(3b82142) | ## Nebula Exchange Nebula Exchange(简称Exchange)是一款Apache Spark™应用,用于在分布式环境中将集群中的数据批量迁移到Nebula Graph中,能支持多种不同格式的批式数据和流式数据的迁移。详情请参见[什么是Nebula Exchange](../nebula-exchange/about-exchange/ex-ug-what-is-exchange.md)。 -|Nebula Graph版本|[Exchange](https://github.com/vesoft-inc/nebula-spark-utils/tree/v2.5/nebula-exchange)版本(commit id)| +|Nebula Graph版本|[Exchange](https://github.com/vesoft-inc/nebula-spark-utils/tree/{{exchange.branch}}/nebula-exchange)版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{exchange.release}}(TODO:coding) | +| {{ nebula.release }} | {{exchange.release}}(3c0f4c6) | ## Nebula Importer Nebula Importer(简称Importer)是一款Nebula Graph的CSV文件导入工具。Importer可以读取本地的CSV文件,然后导入数据至Nebula Graph图数据库中。详情请参见[什么是Nebula Importer](../nebula-importer/use-importer.md)。 -|Nebula Graph版本|[Importer](https://github.com/vesoft-inc/nebula-importer/tree/release-v2.0.0-ga)版本(commit id)| +|Nebula Graph版本|[Importer](https://github.com/vesoft-inc/nebula-importer/tree/{{importer.branch}})版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{importer.release}}(TODO:coding) | +| {{ nebula.release }} | {{importer.release}}(5c7417d) | ## Nebula Spark Connector Nebula Spark Connector是一个Spark连接器,提供通过Spark标准形式读写Nebula Graph数据的能力。Nebula Spark Connector由Reader和Writer两部分组成。详情请参见[什么是Nebula Spark Connector](../nebula-spark-connector.md)。 -|Nebula Graph版本|[Spark Connector](https://github.com/vesoft-inc/nebula-spark-utils/tree/v2.5/nebula-spark-connector)版本(commit id)| +|Nebula Graph版本|[Spark Connector](https://github.com/vesoft-inc/nebula-spark-utils/tree/{{sparkconnector.branch}}/nebula-spark-connector)版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{sparkconnector.release}}(TODO:coding) | +| {{ nebula.release }} | {{sparkconnector.release}}(3c0f4c6) | ## Nebula Flink Connector Nebula Flink Connector是一款帮助Flink用户快速访问Nebula Graph的连接器,支持从Nebula Graph图数据库中读取数据,或者将其他外部数据源读取的数据写入Nebula Graph图数据库。详情请参见[什么是Nebula Flink Connector](../nebula-flink-connector.md)。 -|Nebula Graph版本|[Flink Connector](https://github.com/vesoft-inc/nebula-flink-connector)版本(commit id)| +|Nebula Graph版本|[Flink Connector](https://github.com/vesoft-inc/nebula-flink-connector/tree/{{flinkconnector.branch}})版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{flinkconnector.release}}(TODO:coding) | +| {{ nebula.release }} | {{flinkconnector.release}}(49b8f3d) | ## Nebula Algorithm Nebula Algorithm(简称Algorithm)是一款基于[GraphX](https://spark.apache.org/graphx/)的Spark应用程序,通过提交Spark任务的形式使用完整的算法工具对Nebula Graph数据库中的数据执行图计算,也可以通过编程形式调用lib库下的算法针对DataFrame执行图计算。详情请参见[什么是Nebula Algorithm](../nebula-algorithm.md)。 -|Nebula Graph版本|[Algorithm](https://github.com/vesoft-inc/nebula-spark-utils/tree/v2.5/nebula-algorithm)版本(commit id)| +|Nebula Graph版本|[Algorithm](https://github.com/vesoft-inc/nebula-spark-utils/tree/{{algorithm.branch}}/nebula-algorithm)版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{algorithm.release}}(TODO:coding) | +| {{ nebula.release }} | {{algorithm.release}}(3c0f4c6) | ## Nebula Console @@ -103,7 +100,7 @@ Nebula Console是Nebula Graph的原生CLI客户端。如何使用请参见[连 |Nebula Graph版本|[Console](https://github.com/vesoft-inc/nebula-console)版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{console.release}}(TODO:coding) | +| {{ nebula.release }} | {{console.release}}(3ce5151) | ## Nebula Docker Compose @@ -111,8 +108,9 @@ Docker Compose可以快速部署Nebula Graph集群。如何使用请参见[Docke |Nebula Graph版本|[Docker Compose](https://github.com/vesoft-inc/nebula-docker-compose/tree/master)版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{dockercompose.release}}(TODO:coding) | +| {{ nebula.release }} | {{dockercompose.release}}(d42231f) | + -## Benchmark +## Nebula Bench -[Benchmark](https://github.com/vesoft-inc/nebula-bench) 用于测试 nebula-graph 的基线性能数据,使用 LDBC v0.3.3 的标准数据集。 +[Nebula Bench](https://github.com/vesoft-inc/nebula-bench) 用于测试Nebula Graph的基线性能数据,使用LDBC v0.3.3的标准数据集。 -|Nebula Graph版本|[Benchmark](https://github.com/vesoft-inc/nebula-bench)版本(commit id)| +|Nebula Graph版本|[Nebula Bench](https://github.com/vesoft-inc/nebula-bench)版本(commit id)| |:---|:---| -| {{ nebula.release }} | {{br.release}}(TODO:coding) | - -## Dashboard - -[Dashboard](https://github.com/vesoft-inc/nebula-stats-exporter) 是一款用于监控Nebula Graph集群中机器和服务状态的可视化工具。 - -|Nebula Graph版本|[Dashboard](https://github.com/vesoft-inc/nebula-stats-exporter)版本(commit id)| -|:---|:---| -| {{ nebula.release }} | {{dashboard.release}}(TODO:coding) | - +| {{ nebula.release }} | {{bench.release}}(661f871) | ## API、SDK @@ -146,10 +136,10 @@ Docker Compose可以快速部署Nebula Graph集群。如何使用请参见[Docke |Nebula Graph版本| 语言(commit id) | |:---| :--- | -| {{ nebula.release }}| [C++](https://github.com/vesoft-inc/nebula-cpp)(TODO:coding) | -| {{ nebula.release }}| [Go](https://github.com/vesoft-inc/nebula-go)(TODO:coding) | -| {{ nebula.release }}| [Python](https://github.com/vesoft-inc/nebula-python)(TODO:coding) | -| {{ nebula.release }}| [Java Client](https://github.com/vesoft-inc/nebula-java)(TODO:coding) | +| {{ nebula.release }}| [C++](https://github.com/vesoft-inc/nebula-cpp)(00e2625) | +| {{ nebula.release }}| [Go](https://github.com/vesoft-inc/nebula-go/tree/{{go.branch}})(8a1495a) | +| {{ nebula.release }}| [Python](https://github.com/vesoft-inc/nebula-python)(98e08e4) | +| {{ nebula.release }}| [Java Client](https://github.com/vesoft-inc/nebula-java/tree/{{java.branch}})(0fbc3c6) | ## 未发布 diff --git a/docs-2.0/20.appendix/mind-map.md b/docs-2.0/20.appendix/mind-map.md index 90880132d74..6ffd967fa3a 100644 --- a/docs-2.0/20.appendix/mind-map.md +++ b/docs-2.0/20.appendix/mind-map.md @@ -1,9 +1,9 @@ # 思维导图 -以下给出 Nebula Graph 结构框架的思维导图,用户可以 [点击](https://mubu.com/app/edit/clb/3aWAh5H6Xt#m) 并查看大图。 +以下给出 Nebula Graph 结构框架的思维导图,用户可以 [点击](https://www.mubucm.com/doc/34QEdbrFRwZ) 并查看大图。 ![nebula graph](../20.appendix/Unknown-2.png) -以下给出 nGQL 的思维导图,用户可以 [点击](https://mubu.com/app/edit/clb/1jZHkcX_6DJ#m) 并查看大图。 +以下给出 nGQL 的思维导图,用户可以 [点击](https://www.mubucm.com/doc/3heEUeLwbMZ) 并查看大图。 -![nebula nGQL](../20.appendix/Unknown-3.png) \ No newline at end of file +![nebula nGQL](../20.appendix/Unknown-3.png) diff --git a/docs-2.0/20.appendix/releasenote.md b/docs-2.0/20.appendix/releasenote.md new file mode 100644 index 00000000000..c69461f543e --- /dev/null +++ b/docs-2.0/20.appendix/releasenote.md @@ -0,0 +1,71 @@ +# Nebula Graph {{ nebula.release }} release notes + +## Feature + +- 支持session管理。[#280](https://github.com/vesoft-inc/nebula-graph/pull/280) +- 支持慢查询终止,已知问题:所以query的查询与终止都会有延迟,这与实现方案有关。[#1152](https://github.com/vesoft-inc/nebula-graph/pull/1152) +- Lookup语句增强表达式解析索引的能力。[#1188](https://github.com/vesoft-inc/nebula-graph/pull/1188) +- 支持配置机器内存水位,一定程度上缓解OOM的问题。[1067](https://github.com/vesoft-inc/nebula-graph/pull/1067) +- Find Path支持边过滤。[#1091](https://github.com/vesoft-inc/nebula-graph/pull/1091) +- Subgraph支持只返回图结构,不包含属性。[#1134](https://github.com/vesoft-inc/nebula-graph/pull/1134) +- timestamp函数支持无参数执行。[#515](https://github.com/vesoft-inc/nebula-common/pull/515) +- 支持查询各个服务的版本。[#944](https://github.com/vesoft-inc/nebula-graph/pull/944) +- index和TTL可以同时支持。[#382](https://github.com/vesoft-inc/nebula-storage/pull/382) +- 支持在指定属性创建全文索引。[#460](https://github.com/vesoft-inc/nebula-storage/pull/460) +- 创建space及schema支持comment。[#895](https://github.com/vesoft-inc/nebula-graph/pull/895) +- 支持全文索引重建。[#1123](https://github.com/vesoft-inc/nebula-graph/pull/1123) + +## Enhancement +- listener接口优化,支持获取全量数据,[#465](https://github.com/vesoft-inc/nebula-storage/pull/465)、[#484](https://github.com/vesoft-inc/nebula-storage/pull/484) +- meta的leader表重新组织。[#439](https://github.com/vesoft-inc/nebula-storage/pull/439) +- 增加DiskManager用于检查磁盘剩余容量。[#461](https://github.com/vesoft-inc/nebula-storage/pull/461) +- 优化raft的heartbeat实现。[#438](https://github.com/vesoft-inc/nebula-storage/pull/438) +- storage支持并发执行go/fetch/lookup。 [#503](https://github.com/vesoft-inc/nebula-storage/pull/503) +- 加强了exists函数对map的支持。[#973](https://github.com/vesoft-inc/nebula-graph/pull/973) +- 加强聚合函数的使用方式,比如COUNT(v)+AVG(v)。[#968](https://github.com/vesoft-inc/nebula-graph/pull/968) + +## Bug fix + +- 权限导致的多语句执行问题。[#1165](https://github.com/vesoft-inc/nebula-graph/pull/1165) +- 修复unwind导致没有结果的问题。[#1018](https://github.com/vesoft-inc/nebula-graph/pull/1018) +- 修复聚合函数在某些场景下导致的crash问题。[#1015](https://github.com/vesoft-inc/nebula-graph/pull/1015) +- 修复OR表达式在索引匹配中的问题。[#1005](https://github.com/vesoft-inc/nebula-graph/pull/1005) +- 修复函数的大小写敏感问题。[#927](https://github.com/vesoft-inc/nebula-graph/issues/927) +- 修复查询索引创建信息时没有检查tag/edge类型的问题。[#933](https://github.com/vesoft-inc/nebula-graph/pull/933) +- 修复substring函数的bug。[#491](https://github.com/vesoft-inc/nebula-common/pull/491) +- 修复meta不能正确返回leader change。[#423](https://github.com/vesoft-inc/nebula-storage/pull/423) +- 修复LIMIT,ORDER,GROUP语句使用变量的问题。[#1314](https://github.com/vesoft-inc/nebula-graph/pull/1314) +- 修复db_dump工具打印int类型VID的问题。[#533](https://github.com/vesoft-inc/nebula-storage/pull/533) +- 修复balance任务恢复后仍显示FAIL的问题。[#528](https://github.com/vesoft-inc/nebula-storage/pull/528) + +## Changes & Known issues + +- Subgraph语法变化。 + + ```ngql + # 2.5.0版本增加WITH PROP关键字用于输出属性 + GET SUBGRAPH WITH PROP FROM + + # 原有语法将只输出图结构 + GET SUBGRAPH FROM # + ``` + +- 在`ORDER BY`命令后必须使用引用符`$-.`。但在更早的版本中不需要。 + + ```ngql + # 2.5.0版本的ORDER BY命令后需要使用引用符`$-.`。 + nebula> LOOKUP ON player \ + YIELD player.age As playerage \ + | GROUP BY $-.playerage \ + YIELD $-.playerage as age, count(*) AS number \ + | ORDER BY $-.number DESC, $-.age DESC; + + # 之前版本不需要使用引用符`$-.`。 + nebula> LOOKUP ON player \ + YIELD player.age As playerage \ + | GROUP BY $-.playerage \ + YIELD $-.playerage as age, count(*) AS number \ + | ORDER BY number DESC, age DESC; + ``` + +该版本已知bug/issue请参见[issues](https://github.com/vesoft-inc/nebula-graph/issues)。 diff --git a/docs-2.0/3.ngql-guide/1.nGQL-overview/1.overview.md b/docs-2.0/3.ngql-guide/1.nGQL-overview/1.overview.md index aa008801af1..4e7e3ebc4ba 100644 --- a/docs-2.0/3.ngql-guide/1.nGQL-overview/1.overview.md +++ b/docs-2.0/3.ngql-guide/1.nGQL-overview/1.overview.md @@ -2,7 +2,7 @@ nGQL(Nebula Graph Query Language)是Nebula Graph使用的的声明式图查询语言,支持灵活高效的[图模式](3.graph-patterns.md),而且nGQL是为开发和运维人员设计的类SQL查询语言,易于学习。 -nGQL是一个进行中的项目,会持续发布新特性和优化,因此可能会出现语法和实际操作不一致的问题,如果遇到此类问题,请提交[issue](https://github.com/vesoft-inc/nebula/issues)通知Nebula Graph团队。Nebula Graph 2.0及更新版本将支持[openCypher 9](https://www.opencypher.org/resources)。 +nGQL是一个进行中的项目,会持续发布新特性和优化,因此可能会出现语法和实际操作不一致的问题,如果遇到此类问题,请提交[issue](https://github.com/vesoft-inc/nebula/issues)通知Nebula Graph团队。Nebula Graph 2.0及更新版本正在支持[openCypher 9](https://www.opencypher.org/resources)。 ## nGQL可以做什么 @@ -64,7 +64,7 @@ nebula> CREATE TAG player(name string, age int); ## 关于openCypher兼容性 -## 原生 nGQL 和 openCypher 的关系 +### 原生 nGQL 和 openCypher 的关系 原生 nGQL 是由 Nebula Graph 自行创造和实现的图查询语言。OpenCypher 是由 openCypher Implementers Group 组织所开源和维护的图查询语言, @@ -72,13 +72,22 @@ nebula> CREATE TAG player(name string, age int); !!! Note - `nGQL 语言` = `原生 nGQL 语句` + `OpenCypher 兼容语句` + `nGQL 语言` = `原生 nGQL 语句` + `openCypher 兼容语句` -### nGQL完全兼容openCypher 9吗? +!!! Danger "行为未定义" -!!! compatibility "nGQL部分兼容openCypher 9" + 不要在同一个复合语句中,同时使用`原生 nGQL 语句`和`openCypher 兼容语句`,其行为是未定义的。 - 在[Nebula Graph Issues](https://github.com/vesoft-inc/nebula/issues?q=is%3Aissue+is%3Aopen+label%3Aincompatible)中已经列出已知的37处不兼容项。如果发现这种类型的新问题,请提交问题并附带`incompatible`标签。在本文搜索"compatibility"或者“兼容性”查看具体不兼容细节。 +### nGQL 完全兼容 openCypher 9吗? + +不。 + +!!! compatibility "nGQL 部分兼容 openCypher 9 的 DQL" + + nGQL 设计目标为兼容部分 DQL (match)。不计划兼容任何 DDL,DML,DCL。 + + 在[Nebula Graph Issues](https://github.com/vesoft-inc/nebula/issues?q=is%3Aissue+is%3Aopen+label%3Aincompatible)中已经列出已知的多处不兼容项。如果发现这种类型的新问题,请提交问题并附带`incompatible`标签。在本文搜索"compatibility"或者“兼容性”查看具体不兼容细节。 + ### nGQL和openCypher 9的主要差异有哪些? diff --git a/docs-2.0/3.ngql-guide/1.nGQL-overview/3.graph-patterns.md b/docs-2.0/3.ngql-guide/1.nGQL-overview/3.graph-patterns.md index fdc62bcbdf9..2ca32a0769a 100644 --- a/docs-2.0/3.ngql-guide/1.nGQL-overview/3.graph-patterns.md +++ b/docs-2.0/3.ngql-guide/1.nGQL-overview/3.graph-patterns.md @@ -1,6 +1,6 @@ # 模式 -模式(pattern)和图模式匹配,是图查询语言的核心,本文介绍Nebula Graph的各种模式。 +模式(pattern)和图模式匹配,是图查询语言的核心功能,本文介绍 Nebula Graph 设计的各种模式,部分还未实现。 ## 单点模式 @@ -56,7 +56,7 @@ !!! compatibility "openCypher兼容性" - nGQL中的`MATCH`语句尚不支持用`(a:User:Admin)`匹配多个标签。如需匹配多标签可使用过滤条件,如`WHERE "User" IN tags(n) AND "Admin" IN tags(n)`。 + nGQL中的`MATCH`语句不支持用`(a:User:Admin)`匹配多个标签。如需匹配多标签可使用过滤条件,如`WHERE "User" IN tags(n) AND "Admin" IN tags(n)`。 ## 属性模式 diff --git a/docs-2.0/3.ngql-guide/1.nGQL-overview/ngql-style-guide.md b/docs-2.0/3.ngql-guide/1.nGQL-overview/ngql-style-guide.md index d60b0efc90c..9bb1d319fe4 100644 --- a/docs-2.0/3.ngql-guide/1.nGQL-overview/ngql-style-guide.md +++ b/docs-2.0/3.ngql-guide/1.nGQL-overview/ngql-style-guide.md @@ -103,6 +103,20 @@ nGQL没有严格的构建格式要求,但根据恰当而统一的风格创建n RETURN v; ``` +3. 语法关键词大写,变量小写。 + + 不推荐: + + ```ngql + go from "player100" over Follow + ``` + + 推荐: + + ```ngql + GO FROM "player100" OVER follow + ``` + ## Pattern 1. 分行写Pattern时,在表示边的箭头右侧换行,而不是左侧。 diff --git a/docs-2.0/3.ngql-guide/10.tag-statements/1.create-tag.md b/docs-2.0/3.ngql-guide/10.tag-statements/1.create-tag.md index 930febf8dd1..4a92d30590c 100644 --- a/docs-2.0/3.ngql-guide/10.tag-statements/1.create-tag.md +++ b/docs-2.0/3.ngql-guide/10.tag-statements/1.create-tag.md @@ -33,7 +33,7 @@ CREATE TAG [IF NOT EXISTS] |`IF NOT EXISTS`|检测待创建的Tag是否存在,只有不存在时,才会创建Tag。仅检测Tag的名称,不会检测具体属性。| |``|每个图空间内的Tag必须是唯一的。Tag名称设置后无法修改。Tag名称由大小写英文字母、数字或下划线组成,区分大写小,且不可使用[关键字和保留字](../../3.ngql-guide/1.nGQL-overview/keywords-and-reserved-words.md)。| |``|属性名称。每个Tag中的属性名称必须唯一。属性的命名规则与Tag相同。| -|``|属性的数据类型。数据类型的完整说明,请参见[数值类型](../3.data-types/1.numeric.md)、[布尔](../3.data-types/2.boolean.md)等文档。| +|``|属性的数据类型,目前支持[数值](../3.data-types/1.numeric.md)、[布尔](../3.data-types/2.boolean.md)、[字符串](../3.data-types/3.string.md)以及[日期与时间](../3.data-types/4.date-and-time.md)。| |`NULL \| NOT NULL`|指定属性值是否支持为`NULL`。默认值为`NULL`。| |`DEFAULT`|指定属性的默认值。默认值可以是一个文字值或Nebula Graph支持的表达式。如果插入点时没有指定某个属性的值,则使用默认值。| |`COMMENT`|对单个属性或Tag的描述。最大为256字节。默认无描述。| diff --git a/docs-2.0/3.ngql-guide/11.edge-type-statements/1.create-edge.md b/docs-2.0/3.ngql-guide/11.edge-type-statements/1.create-edge.md index 13e19339141..3ba88807761 100644 --- a/docs-2.0/3.ngql-guide/11.edge-type-statements/1.create-edge.md +++ b/docs-2.0/3.ngql-guide/11.edge-type-statements/1.create-edge.md @@ -33,7 +33,7 @@ CREATE EDGE [IF NOT EXISTS] |`IF NOT EXISTS`|检测待创建的Edge type是否存在,只有不存在时,才会创建Edge type。仅检测Edge type的名称,不会检测具体属性。| |``|每个图空间内的Edge type必须是唯一的。Edge type名称设置后无法修改。Edge type名称由大小写英文字母、数字或下划线组成,区分大写小,且不可使用[关键字和保留字](../../3.ngql-guide/1.nGQL-overview/keywords-and-reserved-words.md)。| |``|属性名称。每个Edge type中的属性名称必须唯一。属性的命名规则与Edge type相同。| -|``|属性的数据类型。数据类型的完整说明,请参见[数值类型](../3.data-types/1.numeric.md)、[布尔](../3.data-types/2.boolean.md)等文档。| +|``|属性的数据类型,目前支持[数值](../3.data-types/1.numeric.md)、[布尔](../3.data-types/2.boolean.md)、[字符串](../3.data-types/3.string.md)以及[日期与时间](../3.data-types/4.date-and-time.md)。| |`NULL \| NOT NULL`|指定属性值是否支持为`NULL`。默认值为`NULL`。| |`DEFAULT`|指定属性的默认值。默认值可以是一个文字值或Nebula Graph支持的表达式。如果插入边时没有指定某个属性的值,则使用默认值。| |`COMMENT`|对单个属性或Edge type的描述。最大为256字节。默认无描述。| diff --git a/docs-2.0/3.ngql-guide/13.edge-statements/3.upsert-edge.md b/docs-2.0/3.ngql-guide/13.edge-statements/3.upsert-edge.md index 2119d0b0c0d..78fd063e82f 100644 --- a/docs-2.0/3.ngql-guide/13.edge-statements/3.upsert-edge.md +++ b/docs-2.0/3.ngql-guide/13.edge-statements/3.upsert-edge.md @@ -106,7 +106,7 @@ nebula> UPSERT EDGE on serve \ 上面最后一个示例中,因为`end_year`没有默认值,插入边时,`end_year`默认值为`NULL`,执行`end_year = end_year + 1`后仍为`NULL`。如果`end_year`有默认值,则`end_year = end_year + 1`可以正常执行,例如: ```ngql -nebula> CREATE EDGE serve_with_default(start_year int, end_year DEFAULT 2010); +nebula> CREATE EDGE serve_with_default(start_year int, end_year int DEFAULT 2010); Execution succeeded nebula> UPSERT EDGE on serve_with_default \ diff --git a/docs-2.0/3.ngql-guide/14.native-index-statements/1.create-native-index.md b/docs-2.0/3.ngql-guide/14.native-index-statements/1.create-native-index.md index 50afad496ce..9bb3a0e35c8 100644 --- a/docs-2.0/3.ngql-guide/14.native-index-statements/1.create-native-index.md +++ b/docs-2.0/3.ngql-guide/14.native-index-statements/1.create-native-index.md @@ -12,11 +12,23 @@ `CREATE INDEX`语句用于对Tag、EdgeType或其属性创建原生索引。通常分别称为“Tag索引”、“Edge type索引”和“属性索引”。 -"Tag索引"和"Edge type索引"应用于和"Tag"、"Edge type"(自身)相关的查询,而不是"基于Tag上某属性"的查询。例如用 `LOOKUP` 找到"某种Edge type E"的所有的边。 +- Tag索引和Edge type索引应用于和Tag、Edge type自身相关的查询,例如用`LOOKUP`查找有Tag `player`的所有点。 -"属性索引"目的是"基于属性的查询"。例如基于属性`Age`找到`Age == 19`的所有的点VID。 - -如果已经为"某个Tag T的属性A"建立过属性索引`i_TA`,则没有必要对于`Tag T`额外再建立一个Tag索引`i_T`。这是因为查询引擎可以使用`i_TA`来替代`i_T`。Edge type索引同理。但是,`i_T`却不能替代`i_TA`用于属性查找。 +- “属性索引”应用于基于属性的查询,例如基于属性`age`找到`age == 19`的所有的点。 + +如果已经为Tag `T`的属性`A`建立过属性索引`i_TA`,索引之间的可替代关系如下(Edge type索引同理): + +- 查询引擎可以使用`i_TA`来替代`i_T`。 + +- 在`MATCH`语句中`i_T`不能替代`i_TA`用于属性查找。 + +- 在`LOOKUP`语句中`i_T`可能替代`i_TA`用于属性查找。 + + !!! compatibility "历史版本兼容性" + + 在此前的版本中,`LOOKUP`语句中的Tag或Edge type索引不可替代属性索引用于属性查找。 + +使用替代索引进行查询虽然能获得相同的结果,但查询性能会根据选择的索引有所区别。 !!! caution diff --git a/docs-2.0/3.ngql-guide/16.subgraph-and-path/1.get-subgraph.md b/docs-2.0/3.ngql-guide/16.subgraph-and-path/1.get-subgraph.md index 0ddf75ed3bf..56169573880 100644 --- a/docs-2.0/3.ngql-guide/16.subgraph-and-path/1.get-subgraph.md +++ b/docs-2.0/3.ngql-guide/16.subgraph-and-path/1.get-subgraph.md @@ -11,7 +11,7 @@ GET SUBGRAPH [WITH PROP] [ STEPS] FROM {, ...} [BOTH , ...]; ``` -- `WITH PROP`:展示边的属性。不添加本参数则隐藏边的属性。 +- `WITH PROP`:展示属性。不添加本参数则隐藏属性。 - `step_count`:指定从起始点开始的跳数,返回从0到`step_count`跳的子图。必须是非负整数。默认值为1。 @@ -33,13 +33,13 @@ GET SUBGRAPH [WITH PROP] [ STEPS] FROM {, ...} ```ngql nebula> GET SUBGRAPH 1 STEPS FROM "player100"; - +-------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ - | _vertices | _edges | - +-------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ - | [("player100" :player{age: 42, name: "Tim Duncan"})] | [[:follow "player100"->"player101" @0 {}], [:follow "player100"->"player102" @0 {}], [:serve "player100"->"team200" @0 {}]] | - +-------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ - | [("player102" :player{age: 33, name: "LaMarcus Aldridge"}), ("player101" :player{age: 36, name: "Tony Parker"}), ("team200" :team{name: "Warriors"})] | [[:follow "player102"->"player101" @0 {}]] | - +-------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ + +-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ + | _vertices | _edges | + +-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ + | [("player100" :player{})] | [[:serve "player100"->"team200" @0 {}], [:follow "player100"->"player101" @0 {}], [:follow "player100"->"player102" @0 {}]] | + +-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ + | [("team200" :team{}), ("player101" :player{}), ("player102" :player{})] | [[:follow "player102"->"player101" @0 {}]] | + +-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+ ``` 返回的子图如下。 @@ -50,13 +50,13 @@ GET SUBGRAPH [WITH PROP] [ STEPS] FROM {, ...} ```ngql nebula> GET SUBGRAPH 1 STEPS FROM "player100" IN follow; - +------------------------------------------------------+--------+ - | _vertices | _edges | - +------------------------------------------------------+--------+ - | [("player100" :player{age: 42, name: "Tim Duncan"})] | [] | - +------------------------------------------------------+--------+ - | [] | [] | - +------------------------------------------------------+--------+ + +---------------------------+--------+ + | _vertices | _edges | + +---------------------------+--------+ + | [("player100" :player{})] | [] | + +---------------------------+--------+ + | [] | [] | + +---------------------------+--------+ ``` 因为`player100`没有`follow`类型的入边。所以仅返回点`player100`。 @@ -103,11 +103,11 @@ nebula> go 1 steps from "A" over follow; ```ngql nebula> GET SUBGRAPH 100 STEPS FROM "player141" OUT follow; -+-------------------------------------------------------+------------------------------------------------------+ -| _vertices | _edges | -+-------------------------------------------------------+------------------------------------------------------+ -| [("player141" :player{age: 43, name: "Ray Allen"})] | [[:follow "player141"->"player124" @0 {degree: 9}]] | -+-------------------------------------------------------+------------------------------------------------------+ -| [("player124" :player{age: 33, name: "Rajon Rondo"})] | [[:follow "player124"->"player141" @0 {degree: -1}]] | -+-------------------------------------------------------+------------------------------------------------------+ ++-------------------------------------------------------+--------------------------------------------+ +| _vertices | _edges | ++-------------------------------------------------------+--------------------------------------------+ +| [("player141" :player{age: 43, name: "Ray Allen"})] | [[:follow "player141"->"player124" @0 {}]] | ++-------------------------------------------------------+--------------------------------------------+ +| [("player124" :player{age: 33, name: "Rajon Rondo"})] | [[:follow "player124"->"player141" @0 {}]] | ++-------------------------------------------------------+--------------------------------------------+ ``` diff --git a/docs-2.0/3.ngql-guide/16.subgraph-and-path/2.find-path.md b/docs-2.0/3.ngql-guide/16.subgraph-and-path/2.find-path.md index 02f819f18df..18c679d10e8 100644 --- a/docs-2.0/3.ngql-guide/16.subgraph-and-path/2.find-path.md +++ b/docs-2.0/3.ngql-guide/16.subgraph-and-path/2.find-path.md @@ -20,13 +20,13 @@ OVER [REVERSELY | BIDIRECT] [] [UPTO STEPS] [ - `WITH PROP`:展示点和边的属性。不添加本参数则隐藏属性。 -- ``:点ID列表.多个点用英文逗号(,)分隔。支持`$-`和`$var`。 +- ``:点ID列表。多个点用英文逗号(,)分隔。支持`$-`和`$var`。 -- ``:Edge type列表.多个Edge type用英文逗号(,)分隔。`*`表示所有Edge type。 +- ``:Edge type列表。多个Edge type用英文逗号(,)分隔。`*`表示所有Edge type。 - `REVERSELY | BIDIRECT`:`REVERSELY`表示反向,`BIDIRECT`表示双向。 -- ``:可以使用`WHERE`子句过滤边属性。 +- ``:可以使用`WHERE`子句过滤边属性。 - ``:路径的最大跳数。默认值为`5`。 diff --git a/docs-2.0/3.ngql-guide/18.operation-and-maintenance-statements/4.job-statements.md b/docs-2.0/3.ngql-guide/18.operation-and-maintenance-statements/4.job-statements.md index c00dd4ed43c..1baa86d5e9c 100644 --- a/docs-2.0/3.ngql-guide/18.operation-and-maintenance-statements/4.job-statements.md +++ b/docs-2.0/3.ngql-guide/18.operation-and-maintenance-statements/4.job-statements.md @@ -4,7 +4,7 @@ ## SUBMIT JOB COMPACT -`SUBMIT JOB COMPACT语句`会触发RocksDB的长耗时`compact`操作。 +`SUBMIT JOB COMPACT` 语句会触发 RocksDB 的长耗时 `compact` 操作。 `compact`配置详情请参见[Storage服务配置](../../5.configurations-and-logs/1.configurations/4.storage-config.md)。 @@ -168,4 +168,4 @@ nebula> RECOVER JOB; ```bash curl "http://{storaged-ip}:19779/admin?space={space_name}&op=compact" -``` \ No newline at end of file +``` diff --git a/docs-2.0/3.ngql-guide/3.data-types/3.string.md b/docs-2.0/3.ngql-guide/3.data-types/3.string.md index 9f41bfe09c5..59b9157a2fe 100644 --- a/docs-2.0/3.ngql-guide/3.data-types/3.string.md +++ b/docs-2.0/3.ngql-guide/3.data-types/3.string.md @@ -33,7 +33,10 @@ nGQL支持以如下方式使用字符串: nebula> CREATE TAG t2 (p2 STRING); ``` -在写入定长字符串时,如果尝试写入的字符串超出长度限制,Nebula Graph将截断字符串,仅存入符合长度限制的部分。例如,当一个图空间的VID类型为`FIXED_STRING(8)`时,如果尝试将`A_string_with_27_characters`设置为VID,然后使用nGQL命令查询该VID,获取到的只有`A_string`。 +如果尝试写入的定长字符串超出长度限制: + +- 当该定长字符串为属性值时,写入会成功,Nebula Graph将截断字符串,仅存入符合长度限制的部分。 +- 当该定长字符串为VID时,写入会失败,Nebula Graph将报错。 ## 转义字符 diff --git a/docs-2.0/3.ngql-guide/3.data-types/4.date-and-time.md b/docs-2.0/3.ngql-guide/3.data-types/4.date-and-time.md index e7e14dd75af..3a7946eeee2 100644 --- a/docs-2.0/3.ngql-guide/3.data-types/4.date-and-time.md +++ b/docs-2.0/3.ngql-guide/3.data-types/4.date-and-time.md @@ -129,11 +129,11 @@ ```ngql nebula> WITH time({hour: 12, minute: 31, second: 14}) AS d RETURN d; -+--------------+ -| d | -+--------------+ -| 12:31:14.000 | -+--------------+ ++-----------------+ +| d | ++-----------------+ +| 12:31:14.000000 | ++-----------------+ nebula> WITH date({year: 1984, month: 10, day: 11}) AS x RETURN x + 1; +------------+ diff --git a/docs-2.0/3.ngql-guide/3.data-types/6.list.md b/docs-2.0/3.ngql-guide/3.data-types/6.list.md index 2caad21acf5..489bf92ba5a 100644 --- a/docs-2.0/3.ngql-guide/3.data-types/6.list.md +++ b/docs-2.0/3.ngql-guide/3.data-types/6.list.md @@ -217,6 +217,6 @@ nebula> MATCH p = (n:player{name:"Tim Duncan"})-[:follow]->(m) \ - 复合数据类型(例如set、map、list)**不能**存储为点或边的属性。 - + 建议修改图建模方式:将复合数据类型建模为点的邻边,而不是该点的自身属性,每条邻边可以动态增删,并且可以设置邻边的 Rank 值来控制邻边的顺序。 + - 建议修改图建模方式:将复合数据类型建模为点的邻边,而不是该点的自身属性,每条邻边可以动态增删,并且可以设置邻边的 Rank 值来控制邻边的顺序。 - List中不支持pattern,例如 `[(src)-[]->(m) | m.name]`。 diff --git a/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/1.composite-queries.md b/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/1.composite-queries.md index 0eefb360805..eefeadaa195 100644 --- a/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/1.composite-queries.md +++ b/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/1.composite-queries.md @@ -14,10 +14,15 @@ Nebula Graph支持三种方式进行复合查询(或子查询): 在复合查询中,请**不要**混用opencypher兼容语句和原生nGQL语句,例如`MATCH ... | GO ... | YIELD ...`,混用两种语句,行为是未定义的。 -- 如果使用opencypher兼容语句(`MATCH`、`RETURN`、`WITH`等),请不要使用管道符或分号组合子句。 +- 如果使用openCypher兼容语句(`MATCH`、`RETURN`、`WITH`等),请不要使用管道符或分号组合子句。 - 如果使用原生nGQL语句(`FETCH`、`GO`、`LOOKUP`等),必须使用管道符或分号组合子句。 + +!!! Danger "行为未定义" + + 不要混用 openCypher 兼容语句和原生 nGQL语句,行为是未定义的。 + ## 复合查询不支持事务 例如一个查询由三个子查询A、B、C组成,A是一个读操作,B是一个计算操作,C是一个写操作,如果在执行过程中,任何一个操作执行失败,则整个结果是未定义的:没有回滚,而且写入的内容取决于执行程序。 diff --git a/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/2.user-defined-variables.md b/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/2.user-defined-variables.md index b0ddf1bb37d..0f005f75250 100644 --- a/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/2.user-defined-variables.md +++ b/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/2.user-defined-variables.md @@ -21,7 +21,7 @@ nebula> MATCH (v:player{name:"Tim Duncan"}) RETURN v; nGQL扩展的自定义变量可以表示为`$var_name`,`var_name`由字母、数字或下划线(_)构成,不允许使用其他字符。 -自定义变量仅在当前执行有效,执行结束后变量也会释放,**不能**在其他客户端或执行中使用之前的自定义变量。 +自定义变量仅在当前执行(本复合查询中)有效,执行结束后变量也会释放,**不能**在其他客户端、执行、session中使用之前的自定义变量。 用户可以在复合查询中使用自定义变量。复合查询的详细信息请参见[复合查询](1.composite-queries.md)。 @@ -33,8 +33,8 @@ nGQL扩展的自定义变量可以表示为`$var_name`,`var_name`由字母、 ```ngql nebula> $var = GO FROM "player100" OVER follow YIELD follow._dst AS id; \ -GO FROM $var.id OVER serve YIELD $$.team.name AS Team, \ -$^.player.name AS Player; + GO FROM $var.id OVER serve YIELD $$.team.name AS Team, \ + $^.player.name AS Player; +---------+-------------+ | Team | Player | +---------+-------------+ diff --git a/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/3.property-reference.md b/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/3.property-reference.md index 11365a1a412..33a82c0bca7 100644 --- a/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/3.property-reference.md +++ b/docs-2.0/3.ngql-guide/4.variable-and-composite-queries/3.property-reference.md @@ -53,8 +53,8 @@ $$.. |:----------|:------------------| |`_src`|边的起始点 | |`_dst`|边的目的点| -|`_type`|边的类型内部编码,正负号表示方向| -|`_rank`|边的rank值| +|`_type`|边的类型内部编码,正负号表示方向:正数为正向边,负数为逆向边| +|`_rank`|边的 rank 值| ## 示例 @@ -79,7 +79,7 @@ nebula> GO FROM "player100" OVER follow YIELD follow.degree; | 90 | +---------------+ -# 返回Edge type follow的起始点、目的点、Edge type编码和边rank值。 +# 返回EdgeType 是 follow 的起始点 VID、目的点 VID、EdgeType 编码(正数为正向边,负数为逆向边),和边的 rank 值。 nebula> GO FROM "player100" OVER follow YIELD follow._src, follow._dst, follow._type, follow._rank; +-------------+-------------+--------------+--------------+ | follow._src | follow._dst | follow._type | follow._rank | diff --git a/docs-2.0/3.ngql-guide/5.operators/4.pipe.md b/docs-2.0/3.ngql-guide/5.operators/4.pipe.md index 4906fd9f580..997a7c26f6c 100644 --- a/docs-2.0/3.ngql-guide/5.operators/4.pipe.md +++ b/docs-2.0/3.ngql-guide/5.operators/4.pipe.md @@ -18,8 +18,8 @@ nGQL和SQL之间的一个主要区别是子查询的组成方式。 ```ngql nebula> GO FROM "player100" OVER follow \ -YIELD follow._dst AS dstid, $$.player.name AS Name | \ -GO FROM $-.dstid OVER follow; + YIELD follow._dst AS dstid, $$.player.name AS Name | \ + GO FROM $-.dstid OVER follow; +-------------+ | follow._dst | diff --git a/docs-2.0/3.ngql-guide/5.operators/6.set.md b/docs-2.0/3.ngql-guide/5.operators/6.set.md index eab4d94fd65..d7edceb037c 100644 --- a/docs-2.0/3.ngql-guide/5.operators/6.set.md +++ b/docs-2.0/3.ngql-guide/5.operators/6.set.md @@ -25,8 +25,8 @@ ```ngql # 返回两个查询结果的并集,不包含重复的元素。 nebula> GO FROM "player102" OVER follow \ - UNION \ - GO FROM "player100" OVER follow; + UNION \ + GO FROM "player100" OVER follow; +-------------+ | follow._dst | +-------------+ @@ -37,8 +37,8 @@ nebula> GO FROM "player102" OVER follow \ # 返回两个查询结果的并集,包含重复的元素。 nebula> GO FROM "player102" OVER follow \ - UNION ALL \ - GO FROM "player100" OVER follow; + UNION ALL \ + GO FROM "player100" OVER follow; +-------------+ | follow._dst | +-------------+ diff --git a/docs-2.0/3.ngql-guide/5.operators/7.string.md b/docs-2.0/3.ngql-guide/5.operators/7.string.md index a73dd9cb9fe..a1b45669b68 100644 --- a/docs-2.0/3.ngql-guide/5.operators/7.string.md +++ b/docs-2.0/3.ngql-guide/5.operators/7.string.md @@ -40,7 +40,7 @@ nebula> UNWIND 'a' AS a UNWIND 'b' AS b RETURN a + b; ```ngql nebula> MATCH (s:player)-[e:serve]->(t:team) WHERE id(s) == "player101" \ - AND t.name CONTAINS "ets" RETURN s.name, e.start_year, e.end_year, t.name; + AND t.name CONTAINS "ets" RETURN s.name, e.start_year, e.end_year, t.name; +---------------+--------------+------------+-----------+ | s.name | e.start_year | e.end_year | t.name | +---------------+--------------+------------+-----------+ @@ -48,8 +48,8 @@ nebula> MATCH (s:player)-[e:serve]->(t:team) WHERE id(s) == "player101" \ +---------------+--------------+------------+-----------+ nebula> GO FROM "player101" OVER serve WHERE (STRING)serve.start_year CONTAINS "19" AND \ - $^.player.name CONTAINS "ny" \ - YIELD $^.player.name, serve.start_year, serve.end_year, $$.team.name; + $^.player.name CONTAINS "ny" \ + YIELD $^.player.name, serve.start_year, serve.end_year, $$.team.name; +----------------+------------------+----------------+--------------+ | $^.player.name | serve.start_year | serve.end_year | $$.team.name | +----------------+------------------+----------------+--------------+ @@ -57,7 +57,7 @@ nebula> GO FROM "player101" OVER serve WHERE (STRING)serve.start_year CONTAINS " +----------------+------------------+----------------+--------------+ nebula> GO FROM "player101" OVER serve WHERE !($$.team.name CONTAINS "ets") \ - YIELD $^.player.name, serve.start_year, serve.end_year, $$.team.name; + YIELD $^.player.name, serve.start_year, serve.end_year, $$.team.name; +----------------+------------------+----------------+--------------+ | $^.player.name | serve.start_year | serve.end_year | $$.team.name | +----------------+------------------+----------------+--------------+ @@ -68,11 +68,11 @@ nebula> GO FROM "player101" OVER serve WHERE !($$.team.name CONTAINS "ets") \ ### `(NOT) IN` ```ngql -nebula> RETURN 1 IN [1,2,3], "Yao" NOT IN ["Yi", "Tim", "Kobe"], NULL in ["Yi", "Tim", "Kobe"] +nebula> RETURN 1 IN [1,2,3], "Yao" NOT IN ["Yi", "Tim", "Kobe"], NULL IN ["Yi", "Tim", "Kobe"] +----------------+------------------------------------+-------------------------------+ | (1 IN [1,2,3]) | ("Yao" NOT IN ["Yi","Tim","Kobe"]) | (NULL IN ["Yi","Tim","Kobe"]) | +----------------+------------------------------------+-------------------------------+ -| true | true | false | +| true | true | __NULL__ | +----------------+------------------------------------+-------------------------------+ ``` diff --git a/docs-2.0/3.ngql-guide/5.operators/8.list.md b/docs-2.0/3.ngql-guide/5.operators/8.list.md index 87f5fc36045..98ae11abbc0 100644 --- a/docs-2.0/3.ngql-guide/5.operators/8.list.md +++ b/docs-2.0/3.ngql-guide/5.operators/8.list.md @@ -29,7 +29,7 @@ nebula> RETURN NULL IN [NULL, 1]; +--------------------+ | (NULL IN [NULL,1]) | +--------------------+ -| true | +| __NULL__ | +--------------------+ nebula> WITH [2, 3, 4, 5] AS numberlist \ diff --git a/docs-2.0/3.ngql-guide/6.functions-and-expressions/3.date-and-time.md b/docs-2.0/3.ngql-guide/6.functions-and-expressions/3.date-and-time.md index 2a75abd54e7..cef9d856cc6 100644 --- a/docs-2.0/3.ngql-guide/6.functions-and-expressions/3.date-and-time.md +++ b/docs-2.0/3.ngql-guide/6.functions-and-expressions/3.date-and-time.md @@ -21,10 +21,10 @@ Nebula Graph支持以下内置日期时间函数。 ## 示例 ```ngql -> RETURN now(), timestamp(), date(), time(), datetime(), timestamp(); +> RETURN now(), timestamp(), date(), time(), datetime(); +------------+-------------+------------+-----------------+----------------------------+ | now() | timestamp() | date() | time() | datetime() | +------------+-------------+------------+-----------------+----------------------------+ | 1625470028 | 1625470028 | 2021-07-05 | 07:27:07.944000 | 2021-07-05T07:27:07.944000 | +------------+-------------+------------+-----------------+----------------------------+ -``` \ No newline at end of file +``` diff --git a/docs-2.0/3.ngql-guide/6.functions-and-expressions/6.list.md b/docs-2.0/3.ngql-guide/6.functions-and-expressions/6.list.md index e93b2eede00..7a7dc216ae5 100644 --- a/docs-2.0/3.ngql-guide/6.functions-and-expressions/6.list.md +++ b/docs-2.0/3.ngql-guide/6.functions-and-expressions/6.list.md @@ -55,7 +55,7 @@ nebula> MATCH p = (a:player)-[]->(b)-[]->(c:team) \ | [("player100" :player{age: 42, name: "Tim Duncan"}), ("player125" :player{age: 41, name: "Manu Ginobili"}), ("team204" :team{name: "Spurs"})] | +-----------------------------------------------------------------------------------------------------------------------------------------------+ -nebula> MATCH p = (a:player)-[]->(b)-[]->(c:team) WHERE a.name == "Tim Duncan" AND c.name == "Spurs" RETURN relationships(p) +nebula> MATCH p = (a:player)-[]->(b)-[]->(c:team) WHERE a.name == "Tim Duncan" AND c.name == "Spurs" RETURN relationships(p); +-----------------------------------------------------------------------------------------------------------------------------+ | relationships(p) | +-----------------------------------------------------------------------------------------------------------------------------+ diff --git a/docs-2.0/3.ngql-guide/6.functions-and-expressions/7.count.md b/docs-2.0/3.ngql-guide/6.functions-and-expressions/7.count.md index 5ed81fc4ff7..6fa5178aeaf 100644 --- a/docs-2.0/3.ngql-guide/6.functions-and-expressions/7.count.md +++ b/docs-2.0/3.ngql-guide/6.functions-and-expressions/7.count.md @@ -66,7 +66,7 @@ nebula> LOOKUP ON player \ YIELD player.age As playerage \ | GROUP BY $-.playerage \ YIELD $-.playerage as age, count(*) AS number \ - | ORDER BY number DESC, age DESC; + | ORDER BY $-.number DESC, $-.age DESC; +-----+--------+ | age | number | +-----+--------+ diff --git a/docs-2.0/3.ngql-guide/7.general-query-statements/2.match.md b/docs-2.0/3.ngql-guide/7.general-query-statements/2.match.md index 5fb9bcf3204..e0e8769dcc8 100644 --- a/docs-2.0/3.ngql-guide/7.general-query-statements/2.match.md +++ b/docs-2.0/3.ngql-guide/7.general-query-statements/2.match.md @@ -156,11 +156,11 @@ nebula> MATCH (v:player) WHERE v.name == "Tim Duncan" RETURN v; ```ngql nebula> MATCH (v) WHERE id(v) == 'player101' RETURN v; -+---------------------------------------------------+ -| v | -+---------------------------------------------------+ -| (player101) player.name:Tony Parker,player.age:36 | -+---------------------------------------------------+ ++-----------------------------------------------------+ +| v | ++-----------------------------------------------------+ +| ("player101" :player{age: 36, name: "Tony Parker"}) | ++-----------------------------------------------------+ ``` 要匹配多个点的ID,可以用`WHERE id(v) IN [vid_list]`。 @@ -716,6 +716,8 @@ nebula> MATCH p=(v:player{name:"Tim Duncan"})-[*..2]->(v2) \ +----------------------------------------------------------------------+--------+ ``` -## 性能提示 +!!! Performance -Nebula Graph {{ nebula.release }} 中 `MATCH` 语句未进行资源占用和性能调优。较简单的逻辑可以使用 `GO`, `LOOKUP`, `|` 和 `FETCH` 等来替代。 + Nebula Graph {{ nebula.release }} 中 `MATCH` 语句对性能和资源占用进行了初步优化。 + + 较简单的逻辑可以使用 `GO`, `LOOKUP`, `|` 和 `FETCH` 等来替代。 diff --git a/docs-2.0/3.ngql-guide/7.general-query-statements/3.go.md b/docs-2.0/3.ngql-guide/7.general-query-statements/3.go.md index 83f76750b17..906e3f3b97a 100644 --- a/docs-2.0/3.ngql-guide/7.general-query-statements/3.go.md +++ b/docs-2.0/3.ngql-guide/7.general-query-statements/3.go.md @@ -44,7 +44,7 @@ OVER [{REVERSELY | BIDIRECT}] - ``:遍历的Edge type列表。 -- `REVERSELY | BIDIRECT`:默认情况下检索的是``的出边,`REVERSELY`表示反向,即检索入边,`BIDIRECT`表示双向,即检索出边和入边。 +- `REVERSELY | BIDIRECT`:默认情况下检索的是``的出边(正向),`REVERSELY`表示反向,即检索入边;`BIDIRECT` 为双向,即检索正向和反向,通过返回 `._type` 字段判断方向,其正数为正向,负数为反向。 - `WHERE `:指定遍历的过滤条件。用户可以在起始点、目的点和边使用`WHERE`子句,还可以结合`AND`、`OR`、`NOT`、`XOR`一起使用。详情请参见[WHERE](../8.clauses-and-options/where.md)。 diff --git a/docs-2.0/3.ngql-guide/7.general-query-statements/5.lookup.md b/docs-2.0/3.ngql-guide/7.general-query-statements/5.lookup.md index 36c69b628e2..2023d438d1f 100644 --- a/docs-2.0/3.ngql-guide/7.general-query-statements/5.lookup.md +++ b/docs-2.0/3.ngql-guide/7.general-query-statements/5.lookup.md @@ -17,8 +17,14 @@ ## 注意事项 - 索引会导致写性能大幅降低(降低90%甚至更多)。请不要随意在生产环境中使用索引,除非很清楚使用索引对业务的影响。 - -- 如果查询时没有合适的索引,会退化为全表扫描。 + +- 如果用`LOOKUP`语句基于指定属性查询时该属性没有索引,系统会在可用的索引中随机选择一个。 + + 例如,Tag `player`有属性`name`和`age`,Tag `player`本身和属性`name`有索引,而属性`age`没有索引。当运行`LOOKUP ON player WHERE player.age == 36 YIELD player.name;`时,系统会在Tag `player`和属性`age`的索引中随机使用一个。 + + !!! compatibility "历史版本兼容性" + + 在此前的版本中,如果用`LOOKUP`语句基于指定属性查询时该属性没有索引,系统将报错,而不会使用其它索引。 ## 前提条件 @@ -27,7 +33,9 @@ ## 语法 ```ngql -LOOKUP ON { | } [WHERE [AND ...]] [YIELD ]; +LOOKUP ON { | } +[WHERE [AND ...]] +[YIELD ]; [AS ] [, [AS ] ...]; @@ -65,40 +73,27 @@ nebula> REBUILD TAG INDEX index_player; | 15 | +------------+ -nebula> LOOKUP ON player WHERE player.name == "Tony Parker"; +nebula> LOOKUP ON player \ + WHERE player.name == "Tony Parker"; ============ | VertexID | ============ | 101 | ------------ -# 正则表达式匹配 -nebula> LOOKUP ON player WHERE player.name =~ "^.{15,20}$" \ +nebula> LOOKUP ON player \ + WHERE player.name == "Tony Parker" \ YIELD player.name, player.age; -+-------------+----------------------+------------+ -| VertexID | player.name | player.age | -+-------------+----------------------+------------+ -| "player147" | "Amar'e Stoudemire" | 36 | -+-------------+----------------------+------------+ -| "player144" | "Shaquille O'Neal" | 47 | -+-------------+----------------------+------------+ -... - -nebula> LOOKUP ON player WHERE player.name CONTAINS toLower("L") \ - YIELD player.name, player.age; -+-------------+---------------------+------------+ -| VertexID | player.name | player.age | -+-------------+---------------------+------------+ -| "player145" | "JaVale McGee" | 31 | -+-------------+---------------------+------------+ -| "player144" | "Shaquille O'Neal" | 47 | -+-------------+---------------------+------------+ -| "player102" | "LaMarcus Aldridge" | 33 | -+-------------+---------------------+------------+ -... - -nebula> LOOKUP ON player WHERE player.name == "Kobe Bryant" YIELD player.name AS name \ - | GO FROM $-.VertexID OVER serve \ +======================================= +| VertexID | player.name | player.age | +======================================= +| 101 | Tony Parker | 36 | +--------------------------------------- + +nebula> LOOKUP ON player \ + WHERE player.name == "Kobe Bryant" \ + YIELD player.name AS name |\ + GO FROM $-.VertexID OVER serve \ YIELD $-.name, serve.start_year, serve.end_year, $$.team.name; ================================================================== | $-.name | serve.start_year | serve.end_year | $$.team.name | @@ -121,7 +116,8 @@ nebula> REBUILD EDGE INDEX index_follow; | 62 | +------------+ -nebula> LOOKUP ON follow WHERE follow.degree == 90; +nebula> LOOKUP ON follow \ + WHERE follow.degree == 90; +-------------+-------------+---------+ | SrcVID | DstVID | Ranking | +-------------+-------------+---------+ @@ -133,7 +129,9 @@ nebula> LOOKUP ON follow WHERE follow.degree == 90; +-------------+-------------+---------+ ... -nebula> LOOKUP ON follow WHERE follow.degree == 90 YIELD follow.degree; +nebula> LOOKUP ON follow \ + WHERE follow.degree == 90 \ + YIELD follow.degree; +-------------+-------------+---------+---------------+ | SrcVID | DstVID | Ranking | follow.degree | +-------------+-------------+---------+---------------+ @@ -145,8 +143,10 @@ nebula> LOOKUP ON follow WHERE follow.degree == 90 YIELD follow.degree; +-------------+-------------+---------+---------------+ ... -nebula> LOOKUP ON follow WHERE follow.degree == 60 YIELD follow.degree AS Degree \ - | GO FROM $-.DstVID OVER serve \ +nebula> LOOKUP ON follow \ + WHERE follow.degree == 60 \ + YIELD follow.degree AS Degree |\ + GO FROM $-.DstVID OVER serve \ YIELD $-.DstVID, serve.start_year, serve.end_year, $$.team.name; +-------------+------------------+----------------+--------------+ | $-.DstVID | serve.start_year | serve.end_year | $$.team.name | @@ -163,7 +163,7 @@ nebula> LOOKUP ON follow WHERE follow.degree == 60 YIELD follow.degree AS Degree 如果需要通过Tag列出所有的点,或通过Edge type列出边,则Tag、Edge type或属性上必须有至少一个索引。 -例如一个Tag`player`有两个属性`name`和`age`,为了遍历所有包含Tag`player`的点ID,Tag`player`、属性`name`或属性`age`中必须有一个已经创建索引。 +例如一个Tag `player`有属性`name`和`age`,为了遍历所有包含Tag `player`的点ID,Tag `player`、属性`name`或属性`age`中必须有一个已经创建索引。 - 查找所有Tag为`player`的点 VID。 @@ -179,7 +179,8 @@ nebula> LOOKUP ON follow WHERE follow.degree == 60 YIELD follow.degree AS Degree | 66 | +------------+ - nebula> INSERT VERTEX player(name,age) VALUES "player100":("Tim Duncan", 42), "player101":("Tony Parker", 36); + nebula> INSERT VERTEX player(name,age) \ + VALUES "player100":("Tim Duncan", 42), "player101":("Tony Parker", 36); # 列出所有的 player。类似于 MATCH (n:player) RETURN id(n) /*, n */。 @@ -207,7 +208,8 @@ nebula> LOOKUP ON follow WHERE follow.degree == 60 YIELD follow.degree AS Degree | 88 | +------------+ - nebula> INSERT EDGE like(likeness) values "player100"->"player101":(95); + nebula> INSERT EDGE like(likeness) \ + VALUES "player100"->"player101":(95); # 列出所有的 like 边。类似于 MATCH (s)-[e:like]->(d) RETURN id(s), rank(e), id(d) /*, type(e) */。 @@ -224,14 +226,16 @@ nebula> LOOKUP ON follow WHERE follow.degree == 60 YIELD follow.degree AS Degree 统计Tag为`player`的点和Edge type为`like`的边。 ```ngql -nebula> LOOKUP ON player | YIELD COUNT(*) AS Player_Number; +nebula> LOOKUP ON player |\ + YIELD COUNT(*) AS Player_Number; +---------------+ | Player_Number | +---------------+ | 2 | +---------------+ -nebula> LOOKUP ON like | YIELD COUNT(*) AS Like_Number; +nebula> LOOKUP ON like | \ + YIELD COUNT(*) AS Like_Number; +-------------+ | Like_Number | +-------------+ @@ -242,4 +246,3 @@ nebula> LOOKUP ON like | YIELD COUNT(*) AS Like_Number; !!! note 使用[`show-stats`命令](./6.show/14.show-stats.md)也可以统计点和边。 - diff --git a/docs-2.0/3.ngql-guide/7.general-query-statements/6.show/6.show-hosts.md b/docs-2.0/3.ngql-guide/7.general-query-statements/6.show/6.show-hosts.md index 3412329fe9e..d7a87059612 100644 --- a/docs-2.0/3.ngql-guide/7.general-query-statements/6.show/6.show-hosts.md +++ b/docs-2.0/3.ngql-guide/7.general-query-statements/6.show/6.show-hosts.md @@ -25,35 +25,35 @@ nebula> SHOW HOSTS; +-------------+-------+----------+--------------+----------------------------------+-----------------------------+ nebula> SHOW HOSTS GRAPH; -+-----------+------+----------+---------+--------------+---------------------------------------------+ -| Host | Port | Status | Role | Git Info Sha | Version | -+-----------+------+----------+---------+--------------+---------------------------------------------+ -| "graphd" | 9669 | "ONLINE" | "GRAPH" | "5368115" | "5368115, Build Time: Jul 19 2021 02:31:12" | -+-----------+------+----------+---------+--------------+---------------------------------------------+ -| "graphd1" | 9669 | "ONLINE" | "GRAPH" | "5368115" | "5368115, Build Time: Jul 19 2021 02:31:12" | -+-----------+------+----------+---------+--------------+---------------------------------------------+ -| "graphd2" | 9669 | "ONLINE" | "GRAPH" | "5368115" | "5368115, Build Time: Jul 19 2021 02:31:12" | -+-----------+------+----------+---------+--------------+---------------------------------------------+ ++-----------+------+----------+---------+---------------+------------------------------------------+ +| Host | Port | Status | Role | Git Info Sha | Version | ++-----------+------+----------+---------+--------------+-------------------------------------------+ +| "graphd" | 9669 | "ONLINE" | "GRAPH" | "c397299c" | "2.5.0, Build Time: Aug 19 2021 11:20:18" | ++-----------+------+----------+---------+--------------+-------------------------------------------+ +| "graphd1" | 9669 | "ONLINE" | "GRAPH" | "c397299c" | "2.5.0, Build Time: Aug 19 2021 11:20:18" | ++-----------+------+----------+---------+--------------+-------------------------------------------+ +| "graphd2" | 9669 | "ONLINE" | "GRAPH" | "c397299c" | "2.5.0, Build Time: Aug 19 2021 11:20:18" | ++-----------+------+----------+---------+--------------+-------------------------------------------+ nebula> SHOW HOSTS STORAGE; -+-------------+------+----------+-----------+--------------+---------------------------------------------+ -| Host | Port | Status | Role | Git Info Sha | Version | -+-------------+------+----------+-----------+--------------+---------------------------------------------+ -| "storaged0" | 9779 | "ONLINE" | "STORAGE" | "0dfa699" | "0dfa699, Build Time: Jul 19 2021 02:22:45" | -+-------------+------+----------+-----------+--------------+---------------------------------------------+ -| "storaged1" | 9779 | "ONLINE" | "STORAGE" | "0dfa699" | "0dfa699, Build Time: Jul 19 2021 02:22:45" | -+-------------+------+----------+-----------+--------------+---------------------------------------------+ -| "storaged2" | 9779 | "ONLINE" | "STORAGE" | "0dfa699" | "0dfa699, Build Time: Jul 19 2021 02:22:45" | -+-------------+------+----------+-----------+--------------+---------------------------------------------+ ++-------------+------+----------+-----------+--------------+-------------------------------------------+ +| Host | Port | Status | Role | Git Info Sha | Version | ++-------------+------+----------+-----------+--------------+-------------------------------------------+ +| "storaged0" | 9779 | "ONLINE" | "STORAGE" | "5b83e5cb" | "2.5.0, Build Time: Aug 19 2021 10:30:28" | ++-------------+------+----------+-----------+--------------+-------------------------------------------+ +| "storaged1" | 9779 | "ONLINE" | "STORAGE" | "5b83e5cb" | "2.5.0, Build Time: Aug 19 2021 10:30:28" | ++-------------+------+----------+-----------+--------------+-------------------------------------------+ +| "storaged2" | 9779 | "ONLINE" | "STORAGE" | "5b83e5cb" | "2.5.0, Build Time: Aug 19 2021 10:30:28" | ++-------------+------+----------+-----------+--------------+-------------------------------------------+ nebula> SHOW HOSTS META; -+----------+------+----------+--------+--------------+---------------------------------------------+ -| Host | Port | Status | Role | Git Info Sha | Version | -+----------+------+----------+--------+--------------+---------------------------------------------+ -| "metad2" | 9559 | "ONLINE" | "META" | "0dfa699" | "0dfa699, Build Time: Jul 19 2021 02:23:49" | -+----------+------+----------+--------+--------------+---------------------------------------------+ -| "metad0" | 9559 | "ONLINE" | "META" | "0dfa699" | "0dfa699, Build Time: Jul 19 2021 02:23:49" | -+----------+------+----------+--------+--------------+---------------------------------------------+ -| "metad1" | 9559 | "ONLINE" | "META" | "0dfa699" | "0dfa699, Build Time: Jul 19 2021 02:23:49" | -+----------+------+----------+--------+--------------+---------------------------------------------+ ++----------+------+----------+--------+--------------+-------------------------------------------+ +| Host | Port | Status | Role | Git Info Sha | Version | ++----------+------+----------+--------+--------------+-------------------------------------------+ +| "metad2" | 9559 | "ONLINE" | "META" | "5b83e5cb" | "2.5.0, Build Time: Aug 19 2021 10:30:28" | ++----------+------+----------+--------+--------------+-------------------------------------------+ +| "metad0" | 9559 | "ONLINE" | "META" | "5b83e5cb" | "2.5.0, Build Time: Aug 19 2021 10:30:28" | ++----------+------+----------+--------+--------------+-------------------------------------------+ +| "metad1" | 9559 | "ONLINE" | "META" | "5b83e5cb" | "2.5.0, Build Time: Aug 19 2021 10:30:28" | ++----------+------+----------+--------+--------------+-------------------------------------------+ ``` diff --git a/docs-2.0/3.ngql-guide/7.general-query-statements/6.show/8.show-indexes.md b/docs-2.0/3.ngql-guide/7.general-query-statements/6.show/8.show-indexes.md index a6d5ea9e1dd..dd9ce30a069 100644 --- a/docs-2.0/3.ngql-guide/7.general-query-statements/6.show/8.show-indexes.md +++ b/docs-2.0/3.ngql-guide/7.general-query-statements/6.show/8.show-indexes.md @@ -1,6 +1,6 @@ # SHOW INDEXES -`SHOW INDEXES`语句显示现有的原生索引。 +`SHOW INDEXES`语句可以列出当前图空间内的所有Tag和Edge type(包括属性)的索引。 ## 语法 @@ -12,18 +12,27 @@ SHOW {TAG | EDGE} INDEXES; ```ngql nebula> SHOW TAG INDEXES; -+------------------+ -| Names | -+------------------+ -| "play_age_0" | -+------------------+ -| "player_index_0" | -+------------------+ ++------------------+--------------+-----------------+ +| Index Name | By Tag | Columns | ++------------------+--------------+-----------------+ +| "fix" | "fix_string" | ["p1"] | ++------------------+--------------+-----------------+ +| "player_index_0" | "player" | ["name"] | ++------------------+--------------+-----------------+ +| "player_index_1" | "player" | ["name", "age"] | ++------------------+--------------+-----------------+ +| "var" | "var_string" | ["p1"] | ++------------------+--------------+-----------------+ nebula> SHOW EDGE INDEXES; -+----------------+ -| Names | -+----------------+ -| "index_follow" | -+----------------+ ++----------------+----------+---------+ +| Index Name | By Edge | Columns | ++----------------+----------+---------+ +| "follow_index" | "follow" | [] | ++----------------+----------+---------+ ``` + + +!!! Compatibility "历史版本兼容性" + + Nebula Graph 2.0.1中, `SHOW TAG/EDGE INDEXES` 语句仅返回 `Names`。 diff --git a/docs-2.0/3.ngql-guide/8.clauses-and-options/limit.md b/docs-2.0/3.ngql-guide/8.clauses-and-options/limit.md index 25d811643e3..94ab6de5624 100644 --- a/docs-2.0/3.ngql-guide/8.clauses-and-options/limit.md +++ b/docs-2.0/3.ngql-guide/8.clauses-and-options/limit.md @@ -31,7 +31,7 @@ YIELD # 从排序结果中返回第2行开始的3行数据。 nebula> GO FROM "player100" OVER follow REVERSELY \ YIELD $$.player.name AS Friend, $$.player.age AS Age \ - | ORDER BY Age,Friend \ + | ORDER BY $-.Age, $-.Friend \ | LIMIT 1, 3; +-------------------+-----+ | Friend | Age | diff --git a/docs-2.0/3.ngql-guide/8.clauses-and-options/order-by.md b/docs-2.0/3.ngql-guide/8.clauses-and-options/order-by.md index 147dc9d8bd7..b147559d96e 100644 --- a/docs-2.0/3.ngql-guide/8.clauses-and-options/order-by.md +++ b/docs-2.0/3.ngql-guide/8.clauses-and-options/order-by.md @@ -18,12 +18,16 @@ ORDER BY [ASC | DESC] [, [ASC | DESC] ...]; ``` +!!! compatibility + + 原生nGQL语法中,`ORDER BY`命令后必须使用引用符`$-.`。但在2.5.0之前的版本中不需要。 + ### 示例 ```ngql nebula> FETCH PROP ON player "player100", "player101", "player102", "player103" \ YIELD player.age AS age, player.name AS name \ - | ORDER BY age ASC, name DESC; + | ORDER BY $-.age ASC, $-.name DESC; +-------------+-----+---------------------+ | VertexID | age | name | +-------------+-----+---------------------+ @@ -111,4 +115,4 @@ nebula> MATCH (v:player{name:"Tim Duncan"}) --> (v2) \ +-----------------+----------+ | "Tony Parker" | 36 | +-----------------+----------+ -``` \ No newline at end of file +``` diff --git a/docs-2.0/3.ngql-guide/8.clauses-and-options/return.md b/docs-2.0/3.ngql-guide/8.clauses-and-options/return.md index 831bf233a08..f8f2e53ef30 100644 --- a/docs-2.0/3.ngql-guide/8.clauses-and-options/return.md +++ b/docs-2.0/3.ngql-guide/8.clauses-and-options/return.md @@ -34,6 +34,26 @@ - 在nGQL 2.0中,`RETURN`不适用于原生nGQL。 +## Map顺序说明 + +`RETURN`返回Map时,Key的顺序是未定义的。 + +```ngql +nebula> RETURN {age: 32, name: "Marco Belinelli"}; ++------------------------------------+ +| {age:32,name:"Marco Belinelli"} | ++------------------------------------+ +| {age: 32, name: "Marco Belinelli"} | ++------------------------------------+ + +nebula> RETURN {zage: 32, name: "Marco Belinelli"}; ++-------------------------------------+ +| {zage:32,name:"Marco Belinelli"} | ++-------------------------------------+ +| {name: "Marco Belinelli", zage: 32} | ++-------------------------------------+ +``` + ## 返回点 ```ngql diff --git a/docs-2.0/3.ngql-guide/8.clauses-and-options/where.md b/docs-2.0/3.ngql-guide/8.clauses-and-options/where.md index afaf2248b96..35643bcec6d 100644 --- a/docs-2.0/3.ngql-guide/8.clauses-and-options/where.md +++ b/docs-2.0/3.ngql-guide/8.clauses-and-options/where.md @@ -182,7 +182,7 @@ nebula> GO FROM "1" \ OVER e1 \ WHERE e1._rank>2 \ YIELD e1._src, e1._dst, e1._rank AS Rank, e1.p1 | \ - ORDER BY Rank DESC; + ORDER BY $-.Rank DESC; ==================================== | e1._src | e1._dst | Rank | e1.p1 | ==================================== diff --git a/docs-2.0/4.deployment-and-installation/1.resource-preparations.md b/docs-2.0/4.deployment-and-installation/1.resource-preparations.md index 177cc0ff0b4..8b30a6ccef3 100644 --- a/docs-2.0/4.deployment-and-installation/1.resource-preparations.md +++ b/docs-2.0/4.deployment-and-installation/1.resource-preparations.md @@ -43,7 +43,7 @@ | xz | 任意稳定版本 | - | | readline-devel | 任意稳定版本 | - | | ncurses-devel | 任意稳定版本 | - | -| zlid-devel | 任意稳定版本 | - | +| zlib-devel | 任意稳定版本 | - | | gcc | 7.5.0及以上 | 执行命令`gcc -v`检查版本。 | | gcc-c++ | 任意稳定版本 | - | | cmake | 3.9.0及以上 | 执行命令`cmake --version`检查版本。 | @@ -117,7 +117,7 @@ 1. 克隆仓库`nebula-common`到主机。 ```bash - $ git clone -b {{common.release}} https://github.com/vesoft-inc/nebula-common.git + $ git clone -b v{{ nebula.release}} https://github.com/vesoft-inc/nebula-common.git ``` 如需安装特定版本的Nebula Graph,使用`--branch`或`-b`选项指定相应的nebula-common分支。 例如,指定{{ nebula.release }},命令如下: @@ -209,7 +209,9 @@ ### 服务架构建议 -!!! danger "**不要**跨机房部署集群" +!!! danger + + **不要**跨机房部署集群。 | 进程 | 数量| | ------------------------| ------| @@ -263,7 +265,7 @@ Nebula Graph 是针对 NVMe SSD 进行设计和实现的,所有默认参数都 - 不要使用远端存储设备(如 NAS 或 SAN),不要外接基于 HDFS 或者 Ceph 的虚拟硬盘。 -- 不需要使用磁盘阵列(RAID); +- 不需要使用磁盘阵列(RAID)。 - 使用本地 SSD 设备。 diff --git a/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/1.install-nebula-graph-by-compiling-the-source-code.md b/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/1.install-nebula-graph-by-compiling-the-source-code.md index cf921adca08..310aee953d4 100644 --- a/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/1.install-nebula-graph-by-compiling-the-source-code.md +++ b/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/1.install-nebula-graph-by-compiling-the-source-code.md @@ -75,6 +75,12 @@ $ sudo make install-all ``` +7. 安装目录下的 `etc/` 目录中(默认为`/usr/local/nebula/etc`)的配置文件为参考模版,用户可以根据需要创建自己的配置文件。如果要使用 `script` 目录下的脚本,启动、停止、重启、中止和查看服务,配置文件需要命名为 `nebula-graph.conf`,`nebula-metad.conf`和`nebula-storaged.conf`。 + + !!! compatibility + + 在 2.0.1 中,可以直接使用 `script` 目录下的脚本,不需要将配置文件重新命名。 + ## 更新master版本 master分支的代码更新速度快,如果安装了master分支对应的开发版Nebula Graph,可根据以下步骤更新版本。 @@ -170,7 +176,7 @@ $ cmake -DCMAKE_C_COMPILER= -DCMAKE_CXX_COMPILER=/nebula-graph-.el7.x86_64.rpm - - //Centos 8 - https://oss-cdn.nebula-graph.com.cn/package//nebula-graph-.el8.x86_64.rpm - - //Ubuntu 1604 - https://oss-cdn.nebula-graph.com.cn/package//nebula-graph-.ubuntu1604.amd64.deb - - //Ubuntu 1804 - https://oss-cdn.nebula-graph.com.cn/package//nebula-graph-.ubuntu1804.amd64.deb - - //Ubuntu 2004 - https://oss-cdn.nebula-graph.com.cn/package//nebula-graph-.ubuntu2004.amd64.deb - ``` - - 例如要下载适用于`Centos 7.5`的`{{ nebula.release }}`安装包: - - ```bash - wget https://oss-cdn.nebula-graph.com.cn/package/{{ nebula.release }}/nebula-graph-{{ nebula.release }}.el7.x86_64.rpm - wget https://oss-cdn.nebula-graph.com.cn/package/{{ nebula.release }}/nebula-graph-{{ nebula.release }}.el7.x86_64.rpm.sha256sum.txt - ``` - - 下载适用于`ubuntu 1804`的`{{ nebula.release }}`安装包: - ```bash - wget https://oss-cdn.nebula-graph.com.cn/package/{{ nebula.release }}/nebula-graph-{{ nebula.release }}.ubuntu1804.amd64.deb - wget https://oss-cdn.nebula-graph.com.cn/package/{{ nebula.release }}/nebula-graph-{{ nebula.release }}.ubuntu1804.amd64.deb.sha256sum.txt - ``` - -- 下载日常开发版本(nightly) - - >**禁止**:nightly版本通常用于测试新功能、新特性,请**不要**在生产环境中使用nightly版本。 - - URL格式如下: - - ```bash - //Centos 7 - https://oss-cdn.nebula-graph.com.cn/package/v2-nightly//nebula-graph--nightly.el7.x86_64.rpm - - //Centos 8 - https://oss-cdn.nebula-graph.com.cn/package/v2-nightly//nebula-graph--nightly.el8.x86_64.rpm - - //Ubuntu 1604 - https://oss-cdn.nebula-graph.com.cn/package/v2-nightly//nebula-graph--nightly.ubuntu1604.amd64.deb - - //Ubuntu 1804 - https://oss-cdn.nebula-graph.com.cn/package/v2-nightly//nebula-graph--nightly.ubuntu1804.amd64.deb - - //Ubuntu 2004 - https://oss-cdn.nebula-graph.com.cn/package/v2-nightly//nebula-graph--nightly.ubuntu1804.amd64.deb - ``` - - 例如要下载`2021.03.28`适用于`Centos 7.5`的`2.x`安装包: - - ```bash - wget https://oss-cdn.nebula-graph.com.cn/package/v2-nightly/2021.03.28/nebula-graph-2021.03.28-nightly.el7.x86_64.rpm - wget https://oss-cdn.nebula-graph.com.cn/package/v2-nightly/2021.03.28/nebula-graph-2021.03.28-nightly.el7.x86_64.rpm.sha256sum.txt - ``` - - 要下载`2021.03.28`适用于`Ubuntu 1804`的`2.x`安装包: - ```bash - wget https://oss-cdn.nebula-graph.com.cn/package/v2-nightly/2021.03.28/nebula-graph-2021.03.28-nightly.ubuntu1804.amd64.deb - wget https://oss-cdn.nebula-graph.com.cn/package/v2-nightly/2021.03.28/nebula-graph-2021.03.28-nightly.ubuntu1804.amd64.deb.sha256sum.txt - ``` - - - -## 安装Nebula Graph - -- 安装RPM包 - - ```bash - $ sudo rpm -ivh --prefix= - ``` - -- 安装DEB包 - - ```bash - $ sudo dpkg -i --instdir== - ``` - -!!! Note - - 如果不设置安装路径,默认安装路径为`/usr/local/nebula/`。 - -## 后续操作 - -- [启动Nebula Graph](../manage-service.md) -- [连接Nebula Graph](../../2.quick-start/3.connect-to-nebula-graph.md) +{% include "/source_install-nebula-graph-by-rpm-or-deb.md" %} + diff --git a/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/3.deploy-nebula-graph-with-docker-compose.md b/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/3.deploy-nebula-graph-with-docker-compose.md index dae71f08211..e040d7fd447 100644 --- a/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/3.deploy-nebula-graph-with-docker-compose.md +++ b/docs-2.0/4.deployment-and-installation/2.compile-and-install-nebula-graph/3.deploy-nebula-graph-with-docker-compose.md @@ -27,7 +27,7 @@ `master`分支包含最新的未测试代码。请**不要**在生产环境使用此版本。 ```bash - $ git clone -b {{dockercompose.release}} https://github.com/vesoft-inc/nebula-docker-compose.git + $ git clone -b v{{dockercompose.release}} https://github.com/vesoft-inc/nebula-docker-compose.git ``` 2. 切换至目录`nebula-docker-compose`。 @@ -64,7 +64,7 @@ 1. 使用Nebula Console镜像启动一个容器,并连接到Nebula Graph服务所在的网络(nebula-docker-compose_nebula-net)中。 ```bash - $ docker run --rm -ti --network nebula-docker-compose_nebula-net --entrypoint=/bin/sh vesoft/nebula-console:v2-nightly + $ docker run --rm -ti --network nebula-docker-compose_nebula-net --entrypoint=/bin/sh vesoft/nebula-console:v2.5.0 ``` !!! Note @@ -199,9 +199,9 @@ Removing nebula-docker-compose_metad1_1 ... done Removing network nebula-docker-compose_nebula-net ``` -!!! Note +!!! danger - 命令`docker-compose down -v`将会**删除**所有本地Nebula Graph的数据。如果使用的是developing或nightly版本,并且有一些兼容性问题,请尝试这个命令。 + 命令`docker-compose down -v`的参数`-v`将会**删除**所有本地的数据。如果使用的是nightly版本,并且有一些兼容性问题,请尝试这个命令。 ## 修改配置 @@ -217,7 +217,7 @@ Docker Compose部署的Nebula Graph,配置文件位置为`nebula-docker-compos ```bash graphd: - image: vesoft/nebula-graphd:v2-nightly + image: vesoft/nebula-graphd:v2.5.0 ... ports: - 9669:9669 @@ -244,7 +244,7 @@ graphd: 执行如下命令可以更新Nebula Console客户端镜像。 ```bash -docker pull vesoft/nebula-console:v2-nightly +docker pull vesoft/nebula-console:v2.5.0 ``` ### 如何升级Nebula Graph? diff --git a/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-from-200-to-250.md b/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-from-200-to-250.md index 8dad4cd6691..2229b5129ce 100644 --- a/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-from-200-to-250.md +++ b/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-from-200-to-250.md @@ -10,16 +10,21 @@ Nebula Graph v2.0.x升级至v{{nebula.release}},只需要使用v{{nebula.relea 1. 下载[RPM/DEB包](https://github.com/vesoft-inc/nebula-graph/releases/tag/v{{nebula.release}})。 -2. 停止所有Nebula Graph服务。详情请参见[管理Nebula Graph服务](../../2.quick-start/5.start-stop-service.md)。 +2. 停止所有Nebula Graph服务。详情请参见[管理Nebula Graph服务](../../2.quick-start/5.start-stop-service.md)。建议更新前备份配置文件。 3. 执行如下命令升级: - RPM包 ```bash - $ sudo rpm -Uivh + $ sudo rpm -Uvh + ``` + + 若安装时指定路径,那么升级时也需要指定路径 + + ```bash + $ sudo rpm -Uivh --prefix= ``` - - DEB包 ```bash diff --git a/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-250.md b/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-250.md index 0a7f9da6bf1..36914a79d25 100644 --- a/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-250.md +++ b/docs-2.0/4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-250.md @@ -1,4 +1,4 @@ -# 升级 Nebula Graph 历史版本至 v{{nebula.release}} +# 升级Nebula Graph历史版本至v{{nebula.release}} Nebula Graph历史版本指低于Nebula Graph v2.0.0-GA的版本,本文介绍如何升级历史版本至v{{nebula.release}}。 @@ -273,7 +273,7 @@ Nebula Graph历史版本指低于Nebula Graph v2.0.0-GA的版本,本文介绍 11. 升级其他客户端。 - 所有的客户端都必须升级到支持Nebula Graph v{{nebula.release}} 的版本。包括但不限于[Studio](https://github.com/vesoft-inc/nebula-docker-compose), [Python](https://github.com/vesoft-inc/nebula-python), [Java](https://github.com/vesoft-inc/nebula-java), [go](https://github.com/vesoft-inc/nebula-go), [C++](https://github.com/vesoft-inc/nebula-cpp), [Flink-connector](https://github.com/vesoft-inc/nebula-flink-connector), [Spark-util](https://github.com/vesoft-inc/nebula-spark-utils), [Benchmark](https://github.com/vesoft-inc/nebula-bench)。请找到各 repo 对应的 branch。 + 所有的客户端都必须升级到支持Nebula Graph v{{nebula.release}} 的版本。包括但不限于[Python](https://github.com/vesoft-inc/nebula-python)、[Java](https://github.com/vesoft-inc/nebula-java)、[go](https://github.com/vesoft-inc/nebula-go)、[C++](https://github.com/vesoft-inc/nebula-cpp)、[Flink-connector](https://github.com/vesoft-inc/nebula-flink-connector)、[Spark-util](https://github.com/vesoft-inc/nebula-spark-utils)、[Nebula Bench](https://github.com/vesoft-inc/nebula-bench)。请找到各 repo 对应的 branch。 !!! Note diff --git a/docs-2.0/4.deployment-and-installation/connect-to-nebula-graph.md b/docs-2.0/4.deployment-and-installation/connect-to-nebula-graph.md new file mode 100644 index 00000000000..1c009ff8414 --- /dev/null +++ b/docs-2.0/4.deployment-and-installation/connect-to-nebula-graph.md @@ -0,0 +1,4 @@ +# 连接Nebula Graph服务 + +{% include "/source_connect-to-nebula-graph.md" %} + diff --git a/docs-2.0/4.deployment-and-installation/manage-service.md b/docs-2.0/4.deployment-and-installation/manage-service.md index 0145e7c9fef..c6474392a25 100644 --- a/docs-2.0/4.deployment-and-installation/manage-service.md +++ b/docs-2.0/4.deployment-and-installation/manage-service.md @@ -1,3 +1,4 @@ # 管理Nebula Graph服务 ---8<-- "source_manage-service.md" +{% include "/source_manage-service.md" %} + diff --git a/docs-2.0/5.configurations-and-logs/1.configurations/4.storage-config.md b/docs-2.0/5.configurations-and-logs/1.configurations/4.storage-config.md index 0260a61a078..3932063cb11 100644 --- a/docs-2.0/5.configurations-and-logs/1.configurations/4.storage-config.md +++ b/docs-2.0/5.configurations-and-logs/1.configurations/4.storage-config.md @@ -77,7 +77,7 @@ Storage服务提供了两份初始配置文件`nebula-storaged.conf.default`和` | 名称 | 预设值 | 说明 | | :--------------------------| :-------------- | :------------------------ | |`data_path` | `data/storage` | 数据存储路径,多个路径用英文逗号(,)分隔。一个RocksDB实例对应一个路径。 | -|`minimum_reserved_bytes`|`268435456`|每个数据存储路径的剩余空间最小值,低于该值时,可能会导致集群元数据操作失败。单位:字节。默认为`1073741824`,即1GB。| +|`minimum_reserved_bytes`|`268435456`|每个数据存储路径的剩余空间最小值,低于该值时,可能会导致集群数据写入失败。单位:字节。默认为`1073741824`,即1GB。| |`rocksdb_batch_size` | `4096` | 批量操作的缓存大小。单位:字节。 | |`rocksdb_block_cache` | `4` | BlockBasedTable的默认块缓存大小。单位:兆(MB)。 | |`engine_type` | `rocksdb` | 存储引擎类型。 | diff --git a/docs-2.0/7.data-security/1.authentication/1.authentication.md b/docs-2.0/7.data-security/1.authentication/1.authentication.md index 97d77a272dc..878cf83b33e 100644 --- a/docs-2.0/7.data-security/1.authentication/1.authentication.md +++ b/docs-2.0/7.data-security/1.authentication/1.authentication.md @@ -6,7 +6,7 @@ !!! Note - 默认情况下,身份验证功能是关闭的,输入任意用户名和密码都可以连接到Nebula Graph。 + 默认情况下,身份验证功能是关闭的,用户可以使用root用户名和任意密码连接到Nebula Graph。 Nebula Graph支持两种身份验证方式:本地身份验证和LDAP验证。 @@ -30,4 +30,6 @@ Nebula Graph支持两种身份验证方式:本地身份验证和LDAP验证。 ### 启用LDAP验证 -当前仅企业版支持集成LDAP进行身份验证,详情请参见使用LDAP进行身份验证(TODO: doc)。 \ No newline at end of file +!!! Enterpriseonly + + 当前仅企业版支持集成LDAP进行身份验证,详情请参见使用LDAP进行身份验证。 diff --git a/docs-2.0/7.data-security/1.authentication/2.management-user.md b/docs-2.0/7.data-security/1.authentication/2.management-user.md index d38968f8d65..646a186ba67 100644 --- a/docs-2.0/7.data-security/1.authentication/2.management-user.md +++ b/docs-2.0/7.data-security/1.authentication/2.management-user.md @@ -6,7 +6,7 @@ !!! Note - * 默认情况下,身份验证功能是关闭的,输入任意用户名和密码都可以连接到Nebula Graph。 + * 默认情况下,身份验证功能是关闭的,用户可以使用root用户名和任意密码连接到Nebula Graph。 * 修改权限后,对应的用户需要重新登录才能生效。 @@ -58,6 +58,27 @@ nebula> REVOKE ROLE USER ON basketballplayer FROM user1; ``` +## 查看用户权限(`SHOW ROLES`) + +执行`SHOW ROLES`语句可以显示分配给用户的角色信息。 + +- 语法 + + ```ngql + SHOW ROLES IN ; + ``` + +- 示例 + + ```ngql + nebula> SHOW ROLES IN basketballplayer; + +---------+-----------+ + | Account | Role Type | + +---------+-----------+ + | "user1" | "ADMIN" | + +---------+-----------+ + ``` + ## 修改用户密码(`CHANGE PASSWORD`) 执行`CHANGE PASSWORD`语句可以修改用户密码,修改时需要提供旧密码和新密码。 diff --git a/docs-2.0/7.data-security/1.authentication/3.role-list.md b/docs-2.0/7.data-security/1.authentication/3.role-list.md index cb96c37b709..4bf5761363c 100644 --- a/docs-2.0/7.data-security/1.authentication/3.role-list.md +++ b/docs-2.0/7.data-security/1.authentication/3.role-list.md @@ -57,13 +57,13 @@ Nebula Graph内置了多种角色,说明如下: |权限|God |Admin|DBA|User|Guest|相关语句| |:---|:---|:---|:---|:---|:---|:---| |Read space|Y|Y|Y|Y|Y|`USE`、`DESCRIBE SPACE`| - |Write space|Y|||||`CREATE SPACE`、`DROP SPACE`、`CREATE SNAPSHOT`、`DROP SNAPSHOT`、`BALANCE`、`ADMIN`、`CONFIG`、`INGEST`、`DOWNLOAD`| + |Write space|Y|||||`CREATE SPACE`、`DROP SPACE`、`CREATE SNAPSHOT`、`DROP SNAPSHOT`、`BALANCE DATA`、`BALANCE DATA STOP`、`BALANCE DATA REMOVE`、`BALANCE LEADER`、`ADMIN`、`CONFIG`、`INGEST`、`DOWNLOAD`、`SUBMIT JOB COMPACT`、`SUBMIT JOB FLUSH`、`SUBMIT JOB STATS`、`STOP JOB`、`RECOVER JOB`、`BUILD TAG INDEX`、`BUILD EDGE INDEX`| |Read schema|Y|Y|Y|Y|Y|`DESCRIBE TAG`、`DESCRIBE EDGE`、`DESCRIBE TAG INDEX`、`DESCRIBE EDGE INDEX`| |Write schema|Y|Y|Y|||`CREATE TAG`、`ALTER TAG`、`CREATE EDGE`、`ALTER EDGE`、`DROP TAG`、`DROP EDGE`、`CREATE TAG INDEX`、`CREATE EDGE INDEX`、`DROP TAG INDEX`、`DROP EDGE INDEX`| |Write user|Y|||||`CREATE USER`、`DROP USER`、`ALTER USER`| |Write role|Y|Y||||`GRANT`、`REVOKE`| |Read data|Y|Y|Y|Y|Y|`GO`、`SET`、`PIPE`、`MATCH`、`ASSIGNMENT`、`LOOKUP`、`YIELD`、`ORDER BY`、`FETCH VERTICES`、`Find`、`FETCH EDGES`、`FIND PATH`、`LIMIT`、`GROUP BY`、`RETURN`| - |Write data|Y|Y|Y|Y||`BUILD TAG INDEX`、`BUILD EDGE INDEX`、`INSERT VERTEX`、`UPDATE VERTEX`、`INSERT EDGE`、`UPDATE EDGE`、`DELETE VERTEX`、`DELETE EDGES`| + |Write data|Y|Y|Y|Y||`INSERT VERTEX`、`UPDATE VERTEX`、`INSERT EDGE`、`UPDATE EDGE`、`DELETE VERTEX`、`DELETE EDGES`| |Show operations|Y|Y|Y|Y|Y|`SHOW`、`CHANGE PASSWORD`| >**注意**: diff --git a/docs-2.0/7.data-security/2.backup-restore/3.br-backup-data.md b/docs-2.0/7.data-security/2.backup-restore/3.br-backup-data.md index fd8963fcbb5..442c2f1eef6 100644 --- a/docs-2.0/7.data-security/2.backup-restore/3.br-backup-data.md +++ b/docs-2.0/7.data-security/2.backup-restore/3.br-backup-data.md @@ -52,6 +52,7 @@ $ ./bin/br backup full --meta --storage --user ://\
Schema:可选值为 `local` 和 `hdfs`。
PATH:存储位置的路径。 | string | | --user | 是 | 无 | 登录到 meta/storage 服务所在主机的用户名。 | string | | --verbose | 否 | 无 | 显示的详细信息。 | - | + ## 下一步 备份文件生成后,可以使用BR将备份文件的数据恢复到Nebula Graph中。具体操作,请参见[使用BR恢复数据](4.br-restore-data.md)。 diff --git a/docs-2.0/7.data-security/2.backup-restore/4.br-restore-data.md b/docs-2.0/7.data-security/2.backup-restore/4.br-restore-data.md index 9b16ca9a9fe..1d7868f1c42 100644 --- a/docs-2.0/7.data-security/2.backup-restore/4.br-restore-data.md +++ b/docs-2.0/7.data-security/2.backup-restore/4.br-restore-data.md @@ -2,7 +2,7 @@ 如果使用BR备份了Nebula Graph的数据,可以通过备份文件进行数据恢复。本文介绍如何通过备份文件恢复数据。 -!!! warning +!!! caution 恢复执行成功后,目标集群上已有的数据会被删除,然后替换为备份文件中的数据。建议提前备份目标集群上的数据。 @@ -28,7 +28,7 @@ - 如果使用Alibaba Cloud OSS或Amazon S3保存备份文件,请确保Meta服务器、Storage服务器和BR机器都已安装相应的客户端。详情请参见[Alibaba Cloud ossutil文档](https://www.alibabacloud.com/help/zh/doc-detail/120075.htm#concept-303829)和[Amazon S3 CLI文档](https://docs.amazonaws.cn/cli/latest/userguide/cli-services-s3.html)。 - !!! warning + !!! caution 请创建软链接方便使用ossutil命令。命令为`ln -s // /usr/local/bin/ossutil`,根据实际路径和系统替换内容。 diff --git a/docs-2.0/8.service-tuning/compaction.md b/docs-2.0/8.service-tuning/compaction.md index 29069eee20b..910140cb4cf 100644 --- a/docs-2.0/8.service-tuning/compaction.md +++ b/docs-2.0/8.service-tuning/compaction.md @@ -14,7 +14,10 @@ Nebula Graph有两种类型的`Compaction`操作:自动`Compaction`和全量`C ## 自动`Compaction` -自动`Compaction`是在系统读取数据、写入数据或系统重启时自动触发`Compaction`操作,提升短时间内的读取性能。默认情况下,自动`Compaction`是开启状态,可能在业务高峰期触发,导致意外抢占IO影响业务。如果需要完全手动控制`Compaction`操作,用户可以关闭自动`Compaction`。 +自动`Compaction`是在系统读取数据、写入数据或系统重启时自动触发`Compaction`操作,提升短时间内的读取性能。默认情况下,自动`Compaction`是开启状态,可能在业务高峰期触发,导致意外抢占IO影响业务。 + + ## 全量`Compaction` @@ -76,13 +80,17 @@ nebula> SHOW JOB ; 为保证Nebula Graph的性能,请参考如下操作建议: + - 数据导入完成后,请执行`SUBMIT JOB COMPACT`。 - 业务低峰期(例如凌晨)执行`SUBMIT JOB COMPACT`。 + - 为控制`Compaction`的读写速率,请在配置文件`nebula-storaged.conf`中设置如下两个参数: diff --git a/docs-2.0/README.md b/docs-2.0/README.md index 16499f86cb5..b72dd43ffff 100644 --- a/docs-2.0/README.md +++ b/docs-2.0/README.md @@ -1,6 +1,8 @@ # 欢迎阅读Nebula Graph {{ nebula.release }} 文档 -!!! Note "本文档更新时间{{ now().year }}-{{ now().month }}-{{ now().day }}, [GitHub commit](https://github.com/vesoft-inc/nebula-docs-cn) {{ git.short_commit }}。" +!!! Note "确认正在阅读最新的版本" + + 本文档更新时间{{ now().year }}-{{ now().month }}-{{ now().day }}, [GitHub commit](https://github.com/vesoft-inc/nebula-docs-cn/tree/v{{ nebula.release }}) {{ git.short_commit }}。 Nebula Graph是一款开源的、分布式的、易扩展的原生图数据库,能够承载数千亿个点和数万亿条边的超大规模数据集,并且提供毫秒级查询。 @@ -16,6 +18,7 @@ Nebula Graph是一款开源的、分布式的、易扩展的原生图数据库 - [《开源分布式图数据库 Nebula Graph 完全指南》](https://docs.nebula-graph.com.cn/site/pdf/NebulaGraph-book.pdf) +- [Release note](20.appendix/releasenote.md) - [论坛](https://discuss.nebula-graph.com.cn/) - [项目主页](https://nebula-graph.com.cn/) - [系列视频](https://space.bilibili.com/472621355) @@ -24,13 +27,20 @@ Graph 完全指南》](https://docs.nebula-graph.com.cn/site/pdf/NebulaGraph-boo ## 图例说明 + + + !!! note 额外的信息或者操作相关的提醒等。 !!! caution - 需要严格遵守的注意事项。不遵守caution可能导致系统故障、数据丢失、安全问题等。 + 需要严格遵守的注意事项。不遵守 caution 可能导致系统故障、数据丢失、安全问题等。 !!! danger diff --git a/docs-2.0/nebula-algorithm.md b/docs-2.0/nebula-algorithm.md index 27adda3a823..763f51a551a 100644 --- a/docs-2.0/nebula-algorithm.md +++ b/docs-2.0/nebula-algorithm.md @@ -54,7 +54,7 @@ Nebula Algorithm实现图计算的流程如下: 1. 克隆仓库`nebula-spark-utils`。 ```bash - $ git clone -b {{algorithm.release}} https://github.com/vesoft-inc/nebula-spark-utils.git + $ git clone -b {{algorithm.branch}} https://github.com/vesoft-inc/nebula-spark-utils.git ``` 2. 进入目录`nebula-algorithm`。 @@ -69,11 +69,11 @@ Nebula Algorithm实现图计算的流程如下: $ mvn clean package -Dgpg.skip -Dmaven.javadoc.skip=true -Dmaven.test.skip=true ``` -编译完成后,在目录`nebula-algorithm/target`下生成类似文件`nebula-algorithm-2.0.0.jar`。 +编译完成后,在目录`nebula-algorithm/target`下生成类似文件`nebula-algorithm-{{algorithm.release}}.jar`。 ### Maven远程仓库下载 -[下载地址](https://repo1.maven.org/maven2/com/vesoft/nebula-algorithm/2.0.0/) +[下载地址](https://repo1.maven.org/maven2/com/vesoft/nebula-algorithm/{{algorithm.release}}/) ## 使用方法 @@ -87,7 +87,7 @@ Nebula Algorithm实现图计算的流程如下: com.vesoft nebula-algorithm - 2.0.0 + {{algorithm.release}} ``` @@ -106,7 +106,7 @@ Nebula Algorithm实现图计算的流程如下: !!! note 使用封装好的算法包有一定的局限性,例如落库到Nebula Graph时,落库的图空间中创建的Tag的属性名称必须和代码内预设的名称保持一致。如果用户有开发能力,推荐使用第一种方法。 -1. 设置[配置文件](https://github.com/vesoft-inc/nebula-spark-utils/blob/master/nebula-algorithm/src/main/resources/application.conf)。 +1. 设置[配置文件](https://github.com/vesoft-inc/nebula-spark-utils/blob/{{algorithm.branch}}/nebula-algorithm/src/main/resources/application.conf)。 ```bash { diff --git a/docs-2.0/nebula-dashboard/2.deploy-dashboard.md b/docs-2.0/nebula-dashboard/2.deploy-dashboard.md index fe446f697fc..dd3f9b9161c 100644 --- a/docs-2.0/nebula-dashboard/2.deploy-dashboard.md +++ b/docs-2.0/nebula-dashboard/2.deploy-dashboard.md @@ -26,11 +26,11 @@ Dashboard版本和Nebula Graph的版本对应关系如下。 ## 下载Dashboard -执行如下命令下载压缩包: +根据需要下载 tar 包,建议选择最新版本。 -```bash -wget https://oss-cdn.nebula-graph.com.cn/nebula-graph-dashboard/nebula-graph-dashboard-1.0.0-1.x86_64.tar.gz -``` +| Dashboard 安装包 | Nebula Graph版本 | +| :----- | :----- | +| [nebula-graph-dashboard-{{ dashboard.base100 }}-1.x86_64.tar.gz](https://oss-cdn.nebula-graph.com.cn/nebula-graph-dashboard/{{ dashboard.base100 }}/nebula-graph-dashboard-{{ dashboard.base100 }}-1.x86_64.tar.gz) | 2.5.0 | ## 目录结构说明 @@ -57,7 +57,7 @@ wget https://oss-cdn.nebula-graph.com.cn/nebula-graph-dashboard/nebula-graph-das 在目录`node-exporter`内执行如下命令启动服务: ```bash -$ nohup ./node-exporter --web.listen-address=:9100 & +$ nohup ./node-exporter --web.listen-address=":9100" & ``` 服务启动后,可以在浏览器中输入`:9100`检查服务是否正常启动。 @@ -71,41 +71,52 @@ $ nohup ./node-exporter --web.listen-address=:9100 & 1. 在目录`nebula-stats-exporter`内修改文件`config.yaml`,配置所有服务的HTTP端口,示例如下: ```bash - version: v0.0.2 - nebulaItems: - - instanceName: metad0 - endpointIP: 192.168.xx.1 - endpointPort: 19559 - componentType: metad - - instanceName: metad1 - endpointIP: 192.168.xx.2 - endpointPort: 19559 - componentType: metad - - instanceName: metad2 - endpointIP: 192.168.xx.3 - endpointPort: 19559 - componentType: metad - - instanceName: graphd0 - endpointIP: 192.168.xx.4 - endpointPort: 19669 - componentType: graphd - - instanceName: storaged0 - endpointIP: 192.168.xx.5 - endpointPort: 19779 - componentType: storaged - - instanceName: storaged1 - endpointIP: 192.168.xx.6 - endpointPort: 19779 - componentType: storaged - - instanceName: storaged2 - endpointIP: 192.168.xx.7 - endpointPort: 19779 + version: v0.0.4 + clusters: + - name: nebula + instances: + - name: metad0 + endpointIP: 192.168.8.157 + endpointPort: 19559 + componentType: metad + - name: metad1 + endpointIP: 192.168.8.155 + endpointPort: 19559 + componentType: metad + - name: metad2 + endpointIP: 192.168.8.154 + endpointPort: 19559 + componentType: metad + - name: graphd0 + endpointIP: 192.168.8.157 + endpointPort: 19669 + componentType: graphd + - name: graphd1 + endpointIP: 192.168.8.155 + endpointPort: 19669 + componentType: graphd + - name: graphd2 + endpointIP: 192.168.8.154 + endpointPort: 19669 + componentType: graphd + - name: storaged0 + endpointIP: 192.168.8.157 + endpointPort: 19779 + componentType: storaged + - name: storaged1 + endpointIP: 192.168.8.155 + endpointPort: 19779 + componentType: storaged + - name: storaged2 + endpointIP: 192.168.8.154 + endpointPort: 19779 + componentType: storaged ``` 2. 执行如下命令启动服务: ```bash - $ nohup ./nebula-stats-exporter --bare-metal --bare-metal-config=./config.yaml & + $ nohup ./nebula-stats-exporter --listen-address=":9200" --bare-metal --bare-metal-config=./config.yaml & ``` 服务启动后,可以在浏览器中输入`:9200`检查服务是否正常启动。 @@ -127,6 +138,7 @@ $ nohup ./node-exporter --web.listen-address=:9100 & static_configs: - targets: [ '192.168.xx.100:9200', # nebula-stats-exporter服务的IP地址和端口。 + '192.168.xx.101:9200' ] - job_name: 'node-exporter' static_configs: diff --git a/docs-2.0/nebula-exchange/about-exchange/ex-ug-limitations.md b/docs-2.0/nebula-exchange/about-exchange/ex-ug-limitations.md index 5540a420415..a8ca9ebbee8 100644 --- a/docs-2.0/nebula-exchange/about-exchange/ex-ug-limitations.md +++ b/docs-2.0/nebula-exchange/about-exchange/ex-ug-limitations.md @@ -8,6 +8,7 @@ Nebula Exchange版本(即JAR包版本)和Nebula Graph的版本对应关系 |Exchange client版本|Nebula Graph版本| |:---|:---| +|{{exchange.release}}|{{nebula.release}}| |2.1.0|2.0.0、2.0.1| |2.0-SNAPSHOT|v2-nightly| |2.0.1|2.0.0、2.0.1| diff --git a/docs-2.0/nebula-exchange/parameter-reference/ex-ug-parameter.md b/docs-2.0/nebula-exchange/parameter-reference/ex-ug-parameter.md index 2c34ccf898c..b25020c4591 100644 --- a/docs-2.0/nebula-exchange/parameter-reference/ex-ug-parameter.md +++ b/docs-2.0/nebula-exchange/parameter-reference/ex-ug-parameter.md @@ -22,7 +22,7 @@ |参数|数据类型|默认值|是否必须|说明| |:---|:---|:---|:---|:---| -|`spark.app.name`|string|`Nebula Exchange 2.0`|否|Spark驱动程序名称。| +|`spark.app.name`|string|-|否|Spark驱动程序名称。| |`spark.driver.cores`|int|`1`|否|驱动程序使用的CPU核数,仅适用于集群模式。| |`spark.driver.maxResultSize`|string|`1G`|否|单个Spark操作(例如collect)时,所有分区的序列化结果的总大小限制(字节为单位)。最小值为1M,0表示无限制。| |`spark.executor.memory`|string|`1G`|否|Spark驱动程序使用的内存量,可以指定单位,例如512M、1G。| @@ -49,9 +49,9 @@ |`nebula.user`|string|-|是|拥有Nebula Graph写权限的用户名。| |`nebula.pswd`|string|-|是|用户名对应的密码。| |`nebula.space`|string|-|是|需要导入数据的的图空间名称。| -|`nebula.path.local`|string|`"/tmp"`|否|(TODO:coding)导入SST文件时需要设置本地SST文件路径。| -|`nebula.path.remote`|string|`"/sst"`|否|(TODO:coding)导入SST文件时需要设置远端SST文件路径。| -|`nebula.path.hdfs.namenode`|string|`"hdfs://name_node:9000"`|否|(TODO:coding)导入SST文件时需要设置HDFS的namenode。| +|`nebula.path.local`|string|`"/tmp"`|否|导入SST文件时需要设置本地SST文件路径。| +|`nebula.path.remote`|string|`"/sst"`|否|导入SST文件时需要设置远端SST文件路径。| +|`nebula.path.hdfs.namenode`|string|`"hdfs://name_node:9000"`|否|导入SST文件时需要设置HDFS的namenode。| |`nebula.connection.timeout`|int|`3000`|否|Thrift连接的超时时间,单位为 ms。| |`nebula.connection.retry`|int|`3`|否|Thrift连接重试次数。| |`nebula.execution.retry`|int|`3`|否|nGQL语句执行重试次数。| @@ -70,7 +70,7 @@ |:---|:---|:---|:---|:---| |`tags.name`|string|-|是|Nebula Graph中定义的Tag名称。| |`tags.type.source`|string|-|是|指定数据源。例如`csv`。| -|`tags.type.sink`|string|`client`|是|指定导入方式,可选值为`client`和`SST`(不支持)。| +|`tags.type.sink`|string|`client`|是|指定导入方式,可选值为`client`和`SST`。| |`tags.fields`|list\[string\]|-|是|属性对应的列的表头或列名。如果有表头或列名,请直接使用该名称。如果CSV文件没有表头,用`[_c0, _c1, _c2]`的形式表示第一列、第二列、第三列,以此类推。| |`tags.nebula.fields`|list\[string\]|-|是|Nebula Graph中定义的属性名称,顺序必须和`tags.fields`一一对应。例如`[_c1, _c2]`对应`[name, age]`,表示第二列为属性name的值,第三列为属性age的值。| |`tags.vertex.field`|string|-|是|点ID的列。例如CSV文件没有表头时,可以用`_c0`表示第一列的值作为点ID。| @@ -97,6 +97,19 @@ |:---|:---|:---|:---|:---| |`tags.exec`|string|-|是|查询数据源的语句。例如`select name,age from mooc.users`。| +### MaxCompute源特有参数 + +|参数|数据类型|默认值|是否必须|说明| +|:---|:---|:---|:---|:---| +|`tags.table`|string|-|是|MaxCompute的表名。| +|`tags.project`|string|-|是|MaxCompute的项目名。| +|`tags.odpsUrl`|string|-|是|MaxCompute服务的odpsUrl。地址可根据[阿里云文档](https://help.aliyun.com/document_detail/34951.html)查看。| +|`tags.tunnelUrl`|string|-|是|MaxCompute服务的tunnelUrl。地址可根据[阿里云文档](https://help.aliyun.com/document_detail/34951.html)查看。| +|`tags.accessKeyId`|string|-|是|MaxCompute服务的accessKeyId。| +|`tags.accessKeySecret`|string|-|是|MaxCompute服务的accessKeySecret。| +|`tags.partitionSpec`|string|-|否|MaxCompute表的分区描述。| +|`tags.sentence`|string|-|否|查询数据源的语句。SQL语句中的表名和上方table的值相同。| + ### Neo4j源特有参数 |参数|数据类型|默认值|是否必须|说明| @@ -118,7 +131,17 @@ |`tags.table`|string|-|是|需要作为数据源的表名称。| |`tags.user`|string|-|是|拥有读取权限的MySQL用户名。| |`tags.password`|string|-|是|用户名对应密码。| -|`tags.sentence`|string|-|是|查询数据源的语句。例如`"select teamid, name from basketball.team order by teamid;"`。| +|`tags.sentence`|string|-|是|查询数据源的语句。例如`"select teamid, name from basketball.team order by teamid;"`。| + +### ClickHouse源特有参数 + +|参数|数据类型|默认值|是否必须|说明| +|:---|:---|:---|:---|:---| +|`tags.url`|string|-|是|ClickHouse的JDBC URL。| +|`tags.user`|string|-|是|有读取权限的ClickHouse用户名。| +|`tags.password`|string|-|是|用户名对应密码。| +|`tags.numPartition`|string|-|是|ClickHouse分区数。| +|`tags.sentence`|string|-|是|查询数据源的语句。| ### Hbase源特有参数 @@ -146,6 +169,12 @@ |`tags.topic`|string|-|是|消息类别。| |`tags.interval.seconds`|int|`10`|是|读取消息的间隔。单位:秒。| +### SST源特有参数 + +|参数|数据类型|默认值|是否必须|说明| +|:---|:---|:---|:---|:---| +|`tags.path`|string|-|是|指定需要生成SST文件的源文件的路径。| + ## 边配置 对于不同的数据源,边的配置也有所不同,有很多通用参数,也有部分特有参数,配置时需要配置通用参数和不同数据源的特有参数。 @@ -158,11 +187,11 @@ |:---|:---|:---|:---|:---| |`edges.name`| string|-|是|Nebula Graph中定义的Edge type名称。| |`edges.type.source`|string|-|是|指定数据源。例如`csv`。| -|`edges.type.sink`|string|`client`|是|指定导入方式,可选值为`client`和`SST`(不支持)。| +|`edges.type.sink`|string|`client`|是|指定导入方式,可选值为`client`和`SST`。| |`edges.fields`|list\[string\]|-|是|属性对应的列的表头或列名。如果有表头或列名,请直接使用该名称。如果CSV文件没有表头,用`[_c0, _c1, _c2]`的形式表示第一列、第二列、第三列,以此类推。| |`edges.nebula.fields`|list\[string\]|-|是|Nebula Graph中定义的属性名称,顺序必须和`edges.fields`一一对应。例如`[_c2, _c3]`对应`[start_year, end_year]`,表示第三列为开始年份的值,第四列为结束年份的值。| |`edges.source.field`|string|-|是|边的起始点的列。例如`_c0`表示第一列的值作为边的起始点。| |`edges.target.field`|string|-|是|边的目的点的列。例如`_c1`表示第二列的值作为边的目的点。| |`edges.ranking`|int|-|否|rank值的列。没有指定时,默认所有rank值为`0`。| |`edges.batch`|int|`256`|是|单批次写入Nebula Graph的最大边数量。| -|`edges.partition`|int|`32`|是|Spark分片数量。| \ No newline at end of file +|`edges.partition`|int|`32`|是|Spark分片数量。| diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-kafka.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-kafka.md index a9cd3ae26c8..4870c497756 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-kafka.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-kafka.md @@ -76,6 +76,10 @@ ### 步骤 2:修改配置文件 +!!! note + + 如果部分数据存储在Kafka的value域内,需要自行修改源码,从Kafka中获取value域,将value通过from_json函数解析,然后作为Dataframe返回。 + 编译Exchange后,复制`target/classes/application.conf`文件设置Kafka数据源相关的配置。在本示例中,复制的文件名为`kafka_application.conf`。各个配置项的详细说明请参见[配置说明](../parameter-reference/ex-ug-parameter.md)。 ```conf @@ -142,8 +146,8 @@ # 消息类别。 topic: "topic_name1" - # kafka数据有固定的字段名称:key、value、topic、partition、offset、timestamp、timestampType。 - # 如果需要指定多个列名称,用英文逗号(,)隔开。 + # Kafka数据有固定的域名称:key、value、topic、partition、offset、timestamp、timestampType。 + # Spark读取为DataFrame后,如果需要指定多个字段,用英文逗号(,)隔开。 # 在fields里指定字段名称,例如用key对应Nebula中的name, value对应Nebula中的age,示例如下: fields: [key,value] nebula.fields: [name,age] @@ -205,8 +209,8 @@ # 消息类别。 topic: "topic_name3" - # kafka数据有固定的字段名称:key、value、topic、partition、offset、timestamp、timestampType。 - # 如果需要指定多个列名称,用英文逗号(,)隔开。 + # Kafka数据有固定的域名称:key、value、topic、partition、offset、timestamp、timestampType。 + # Spark读取为DataFrame后,如果需要指定多个字段,用英文逗号(,)隔开。 # 在fields里指定字段名称,例如用key对应Nebula中的degree,示例如下: fields: [key] nebula.fields: [degree] @@ -293,4 +297,4 @@ GO FROM "player100" OVER follow; ### 步骤 5:(如有)在Nebula Graph中重建索引 -导入数据后,用户可以在Nebula Graph中重新创建并重建索引。详情请参见[索引介绍](../../3.ngql-guide/14.native-index-statements/README.md)。 \ No newline at end of file +导入数据后,用户可以在Nebula Graph中重新创建并重建索引。详情请参见[索引介绍](../../3.ngql-guide/14.native-index-statements/README.md)。 diff --git a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-sst.md b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-sst.md index 28824c0ef8d..216a204498a 100644 --- a/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-sst.md +++ b/docs-2.0/nebula-exchange/use-exchange/ex-ug-import-from-sst.md @@ -1,6 +1,6 @@ # 导入SST文件数据 -本文以一个示例说明如何将数据源的数据生成SST(Sorted String Table)文件,然后导入Nebula Graph,示例数据源是CSV文件。 +本文以一个示例说明如何将数据源的数据生成SST(Sorted String Table)文件并保存在HDFS上,然后导入Nebula Graph,示例数据源是CSV文件。 > **说明**:仅Linux系统支持导入SST文件。 @@ -236,8 +236,7 @@ SST文件是一个内部包含了任意长度的有序键值对集合的文件 } # 指定CSV文件的路径。 - # 如果文件存储在HDFS上,用双引号括起路径,以hdfs://开头,例如"hdfs://ip:port/xx/xx"。 - # 如果文件存储在本地,用双引号括起路径,以file://开头,例如"file:///tmp/xx.csv"。 + # 文件存储在HDFS上,用双引号括起路径,以hdfs://开头,例如"hdfs://ip:port/xx/xx"。 path: "hdfs://*.*.*.*:9000/dataset/vertex_player.csv" # 如果CSV文件没有表头,使用[_c0, _c1, _c2, ..., _cn]表示其表头,并将列指示为属性值的源。 @@ -282,8 +281,7 @@ SST文件是一个内部包含了任意长度的有序键值对集合的文件 } # 指定CSV文件的路径。 - # 如果文件存储在HDFS上,用双引号括起路径,以hdfs://开头,例如"hdfs://ip:port/xx/xx"。 - # 如果文件存储在本地,用双引号括起路径,以file://开头,例如"file:///tmp/xx.csv"。 + # 文件存储在HDFS上,用双引号括起路径,以hdfs://开头,例如"hdfs://ip:port/xx/xx"。 path: "hdfs://*.*.*.*:9000/dataset/vertex_team.csv" # 如果CSV文件没有表头,使用[_c0, _c1, _c2, ..., _cn]表示其表头,并将列指示为属性值的源。 @@ -333,8 +331,7 @@ SST文件是一个内部包含了任意长度的有序键值对集合的文件 } # 指定CSV文件的路径。 - # 如果文件存储在HDFS上,用双引号括起路径,以hdfs://开头,例如"hdfs://ip:port/xx/xx"。 - # 如果文件存储在本地,用双引号括起路径,以file://开头,例如"file:///tmp/xx.csv"。 + # 文件存储在HDFS上,用双引号括起路径,以hdfs://开头,例如"hdfs://ip:port/xx/xx"。 path: "hdfs://*.*.*.*:9000/dataset/edge_follow.csv" # 如果CSV文件没有表头,使用[_c0, _c1, _c2, ..., _cn]表示其表头,并将列指示为属性值的源。 @@ -386,8 +383,7 @@ SST文件是一个内部包含了任意长度的有序键值对集合的文件 } # 指定CSV文件的路径。 - # 如果文件存储在HDFS上,用双引号括起路径,以hdfs://开头,例如"hdfs://ip:port/xx/xx"。 - # 如果文件存储在本地,用双引号括起路径,以file://开头,例如"file:///tmp/xx.csv"。 + # 文件存储在HDFS上,用双引号括起路径,以hdfs://开头,例如"hdfs://ip:port/xx/xx"。 path: "hdfs://*.*.*.*:9000/dataset/edge_serve.csv" # 如果CSV文件没有表头,使用[_c0, _c1, _c2, ..., _cn]表示其表头,并将列指示为属性值的源。 diff --git a/docs-2.0/nebula-explorer/deploy-connect/ex-ug-deploy.md b/docs-2.0/nebula-explorer/deploy-connect/ex-ug-deploy.md index 7e373281938..a4f65587bd7 100644 --- a/docs-2.0/nebula-explorer/deploy-connect/ex-ug-deploy.md +++ b/docs-2.0/nebula-explorer/deploy-connect/ex-ug-deploy.md @@ -16,6 +16,8 @@ | ---- | ---- | | 7002 | Explorer 提供的 web 服务 | | 8070 | Nebula-http-gateway 的 HTTP 服务 | + +- 使用的 Linux 发行版为 CentOS ,安装有版本为 v10.16.0 + 以上的 Node.js。 ### 安装 @@ -66,7 +68,7 @@ $ sudo rpm -e nebula-graph-explorer-.x86_64 - Nebula Graph 服务已经部署并启动。详细信息参考[Nebula Graph安装部署](../../4.deployment-and-installation/1.resource-preparations.md "点击前往 Nebula Graph 安装部署")。 -- 使用的 Linux 上安装有版本为 v10.12.0 以上的Node.js。 +- 使用的 Linux 发行版为 CentOS ,安装有版本为 v10.16.0 + 以上的 Node.js。 - 以下端口未被使用。 @@ -127,4 +129,4 @@ $ npm run stop # 停止 nebula-graph-explorer ![Nebula Graph Explorer 登录页面](../figs/ex-ug-001.png) -进入 Explorer 登录界面后,用户需要连接 Nebula Graph。详细信息,参考[连接数据库](../deploy-connect/ex-ug-connect.md)。 \ No newline at end of file +进入 Explorer 登录界面后,用户需要连接 Nebula Graph。详细信息,参考[连接数据库](../deploy-connect/ex-ug-connect.md)。 diff --git a/docs-2.0/nebula-spark-connector.md b/docs-2.0/nebula-spark-connector.md index b2e1da3d85d..e6e26412a47 100644 --- a/docs-2.0/nebula-spark-connector.md +++ b/docs-2.0/nebula-spark-connector.md @@ -36,7 +36,7 @@ Nebula Spark Connector {{sparkconnector.release}}版本特性如下: - Reader支持将Nebula Graph数据读取成Graphx的VertexRDD和EdgeRDD,支持非Long型点ID。 -- Nebula Spark Connector 2.0统一了SparkSQL的扩展数据源,统一采用DataSourceV2进行Nebula Graph数据扩展。 +- 统一了SparkSQL的扩展数据源,统一采用DataSourceV2进行Nebula Graph数据扩展。 - 支持`insert`和`update`两种写入模式。`insert`模式会插入(覆盖)数据,`update`模式仅会更新已存在的数据。 @@ -47,7 +47,7 @@ Nebula Spark Connector {{sparkconnector.release}}版本特性如下: 1. 克隆仓库`nebula-spark-utils`。 ```bash - $ git clone -b {{sparkconnector.release}} https://github.com/vesoft-inc/nebula-spark-utils.git + $ git clone -b {{sparkconnector.branch}} https://github.com/vesoft-inc/nebula-spark-utils.git ``` 2. 进入目录`nebula-spark-connector`。 @@ -215,7 +215,7 @@ df.write.nebula(config, nebulaWriteVertexConfig).writeVertices() |`withSpace` |是| Nebula Graph图空间名称。 | |`withTag` |是| 写入点时需要关联的Tag名称。 | |`withVidField` |是| DataFrame中作为点ID的列。 | - |`withVidPolicy` |否| 写入点ID时,采用的映射函数,Nebula Graph 2.0仅支持HASH。默认不做映射。 | + |`withVidPolicy` |否| 写入点ID时,采用的映射函数,Nebula Graph 2.x仅支持HASH。默认不做映射。 | |`withVidAsProp` |否| DataFrame中作为点ID的列是否也作为属性写入。默认值为`false`。如果配置为`true`,请确保Tag中有和`VidField`相同的属性名。 | |`withUser` |否| Nebula Graph用户名。若未开启[身份验证](7.data-security/1.authentication/1.authentication.md),无需配置用户名和密码。 | |`withPasswd` |否| Nebula Graph用户名对应的密码。 | @@ -229,9 +229,9 @@ df.write.nebula(config, nebulaWriteVertexConfig).writeVertices() |`withSpace` |是| Nebula Graph图空间名称。 | |`withEdge` |是| 写入边时需要关联的Edge type名称。 | |`withSrcIdField` |是| DataFrame中作为起始点的列。 | - |`withSrcPolicy` |否| 写入起始点时,采用的映射函数,Nebula Graph 2.0仅支持HASH。默认不做映射。 | + |`withSrcPolicy` |否| 写入起始点时,采用的映射函数,Nebula Graph 2.x仅支持HASH。默认不做映射。 | |`withDstIdField` |是| DataFrame中作为目的点的列。 | - |`withDstPolicy` |否| 写入目的点时,采用的映射函数,Nebula Graph 2.0仅支持HASH。默认不做映射。 | + |`withDstPolicy` |否| 写入目的点时,采用的映射函数,Nebula Graph 2.x仅支持HASH。默认不做映射。 | |`withRankField` |否| DataFrame中作为rank的列。默认不写入rank。 | |`withSrcAsProperty` |否| DataFrame中作为起始点的列是否也作为属性写入。默认值为`false`。如果配置为`true`,请确保Edge type中有和`SrcIdField`相同的属性名。 | |`withDstAsProperty` |否| DataFrame中作为目的点的列是否也作为属性写入。默认值为`false`。如果配置为`true`,请确保Edge type中有和`DstIdField`相同的属性名。 | diff --git a/docs-2.0/nebula-studio/about-studio/st-ug-what-is-graph-studio.md b/docs-2.0/nebula-studio/about-studio/st-ug-what-is-graph-studio.md index 1d31dc0082a..bde449d0450 100644 --- a/docs-2.0/nebula-studio/about-studio/st-ug-what-is-graph-studio.md +++ b/docs-2.0/nebula-studio/about-studio/st-ug-what-is-graph-studio.md @@ -1,20 +1,20 @@ # 什么是 Nebula Graph Studio -Nebula Graph Studio(简称 Studio)是一款可以通过 Web 访问的图数据库可视化工具,搭配 [Nebula Graph](../../README.md) 内核使用,提供构图、数据导入、编写 nGQL 查询、图探索等一站式服务。即使没有图数据库操作经验,用户也可以快速成为图专家。 +Nebula Graph Studio(简称 Studio)是一款可以通过 Web 访问的图数据库开源可视化工具,搭配 [Nebula Graph](../../README.md) 内核使用,提供构图、数据导入、编写 nGQL 查询、图探索等一站式服务。即使没有图数据库操作经验,用户也可以快速成为图专家。用户可以在 Nebula Graph GitHub 仓库中查看最新源码,详情参见[nebula-studio](https://github.com/vesoft-inc/nebula-studio)。 ## 发行版本 Studio 目前有三个发行版本: -- Docker 版本:用户可以使用 Docker 服务部署 Studio,并连接到 Nebula Graph 数据库。详细信息参考 [部署 Studio](../deploy-connect/st-ug-deploy.md)。 -- RPM 版本:用户可以使用 RPM 服务部署 Studio,并连接到 Nebula Graph 数据库。详细信息参考 [部署 Studio](../deploy-connect/st-ug-deploy.md)。 -- tar 包安装部署:用户可以使用 tar 包安装并部署 Studio,并连接到 Nebula Graph 数据库。详细信息参考 [部署 Studio](../deploy-connect/st-ug-deploy.md)。 +- Docker 版本:用户可以使用 Docker 服务部署 Studio,并连接到 Nebula Graph 数据库。详细信息参考 [Docker 部署 Studio](../deploy-connect/st-ug-deploy.md)。 +- RPM 版本:用户可以使用 RPM 服务部署 Studio,并连接到 Nebula Graph 数据库。详细信息参考 [RPM 部署 Studio](../deploy-connect/st-ug-deploy.md)。 +- tar 包安装部署:用户可以使用 tar 包安装并部署 Studio,并连接到 Nebula Graph 数据库。详细信息参考 [tar 包部署 Studio](../deploy-connect/st-ug-deploy.md)。 -三个发行版本功能基本相同。但是,因为部署方式不同,会有不同的使用限制。详细信息,参考 [使用限制](st-ug-limitations.md)。 +三个发行版本功能基本相同,在使用 Studio 时可能会受到限制。详细信息,参考 [使用限制](st-ug-limitations.md)。 ## 产品功能 diff --git a/docs-2.0/nebula-studio/deploy-connect/st-ug-deploy.md b/docs-2.0/nebula-studio/deploy-connect/st-ug-deploy.md index 2ff9fbbd431..251855dbe02 100644 --- a/docs-2.0/nebula-studio/deploy-connect/st-ug-deploy.md +++ b/docs-2.0/nebula-studio/deploy-connect/st-ug-deploy.md @@ -100,7 +100,7 @@ Nebula Graph Studio( 以下简称 Studio )支持云端或本地部署。云 - Nebula Graph 服务已经部署并启动。详细信息,参考[Nebula Graph 安装部署](../../4.deployment-and-installation/1.resource-preparations.md "点击前往 Nebula Graph 安装部署")。 -- 使用的 Linux 发行版为 CentOS ,安装有 lsof 和版本为 v10.16.0 + 以上的 [Node.js](https://www.softwarecollections.org/en/scls/jstanek/rh-nodejs12/)。 +- 使用的 Linux 发行版为 CentOS ,安装有 lsof 和版本为 v10.16.0 + 以上的 [Node.js](https://nodejs.org/zh-cn/)。 !!! note @@ -126,14 +126,14 @@ Nebula Graph Studio( 以下简称 Studio )支持云端或本地部署。云 | 安装包 | 检验和 | Nebula版本 | | ----- | ----- | ----- | - | [nebula-graph-studio-3.0.0-1.x86_64.rpm](https://oss-cdn.nebula-graph.com.cn/nebula-graph-studio/nebula-graph-studio-3.0.0-1.x86_64.rpm) | [nebula-graph-studio-3.0.0-1.x86_64.rpm.sha256](https://oss-cdn.nebula-graph.com.cn/nebula-graph-studio/nebula-graph-studio-3.0.0-1.x86_64.rpm.sha256) | 2.5.0 | + | [nebula-graph-studio-3.0.0-1.x86_64.rpm](https://oss-cdn.nebula-graph.com.cn/nebula-graph-studio/3.0.0/nebula-graph-studio-3.0.0-1.x86_64.rpm) | [nebula-graph-studio-3.0.0-1.x86_64.rpm.sha256](https://oss-cdn.nebula-graph.com.cn/nebula-graph-studio/3.0.0/nebula-graph-studio-3.0.0-1.x86_64.rpm.sha256) | 2.5.0 | 2. 使用`sudo rpm -i `命令安装RPM包。 - 例如,安装Studio {{ studio.base220 }} 版本需要运行以下命令: + 例如,安装Studio 3.0.0 版本需要运行以下命令: ```bash - $ sudo rpm -i nebula-graph-studio-{{ studio.base220 }}-6.x86_64.rpm + $ sudo rpm -i nebula-graph-studio-3.0.0-1.x86_64.rpm ``` 当屏幕返回以下信息时,表示 PRM 版 Studio 已经成功启动。 @@ -157,7 +157,7 @@ Nebula Graph Studio( 以下简称 Studio )支持云端或本地部署。云 用户可以使用以下的命令卸载 Studio。 ```bash -$ sudo rpm -e nebula-graph-studio-{{ studio.base220 }}-1.x86_64 +$ sudo rpm -e nebula-graph-studio-3.0.0-1.x86_64 ``` ### 异常处理 @@ -219,9 +219,10 @@ $ npm run start ### 安装 1. 根据需要下载 tar 包,建议选择最新版本。 + | 安装包 | Studio 版本 | | --- | --- | - | [nebula-graph-studio-3.0.0-1.x86_64.tar.gz](https://oss-cdn.nebula-graph.com.cn/nebula-graph-studio/nebula-graph-studio-3.0.0-1.x86_64.tar.gz) | 3.0.0 | + | [nebula-graph-studio-3.0.0-1.x86_64.tar.gz](https://oss-cdn.nebula-graph.com.cn/nebula-graph-studio/3.0.0/nebula-graph-studio-3.0.0-1.x86_64.tar.gz) | 3.0.0 | 2. 使用 `tar -xvf` 解压 tar 包。 diff --git a/docs-2.0/reuse/assets.png b/docs-2.0/reuse/assets.png new file mode 100644 index 0000000000000000000000000000000000000000..f0dba0f5374229aee0443572ed9abd13b1a3de34 GIT binary patch literal 60450 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

}xhFtvzB9{T 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 TUYlFp1$ -port -u -p - [-t 120] [-e "nGQL_statement" | -f filename.nGQL] + [-t 120] [-e "nGQL_statement" | -f filename.nGQL] ``` - - Windows + - Windows ```powershell > nebula-console.exe -addr -port -u -p - [-t 120] [-e "nGQL_statement" | -f filename.nGQL] + [-t 120] [-e "nGQL_statement" | -f filename.nGQL] ``` - 参数说明如下。 + 参数说明如下。 | 参数 | 说明 | | - | - | @@ -79,31 +79,124 @@ Nebula Graph支持多种类型客户端,包括CLI客户端、GUI客户端和 用户可以使用`./nebula-console --help`命令获取所有参数的说明,也可以在[项目仓库](https://github.com/vesoft-inc/nebula-console/tree/v2.0.0-ga)找到更多说明。 -## Nebula Console导出模式 +## Nebula Console命令 + +Nebula Console提供部分命令,可以导出CSV文件、导出DOT文件、导入测试数据集等。 + +!!! note + + 命令不区分大小写。 + +### 导出CSV文件 + +!!! note + + - CSV文件保存在当前工作目录中,即Linux命令`pwd`显示的目录。 + + - 命令只对下一条查询语句生效。 -导出模式开启时,Nebula Console会导出所有请求的结果到CSV格式文件中。关闭导出模式会停止导出。使用语法如下: +导出CSV文件命令如下: + +```ngql +nebula> :CSV +``` + +### 导出DOT文件 !!! Note - - 命令不区分大小写。 - - CSV格式文件保存在当前工作目录中,即Linux命令`pwd`显示的目录。 + - DOT文件保存在当前工作目录中,即Linux命令`pwd`显示的目录。 + + - DOT文件的内容可以复制后在[GraphvizOnline](https://dreampuf.github.io/GraphvizOnline/)网页中粘贴,生成可视化的执行计划图。 + + - 命令只对下一条查询语句生效。 + +导出DOT文件命令如下: + +```ngql +nebula> :dot +``` + +示例: + +```ngql +nebula> :dot a.dot +nebula> PROFILE FORMAT="dot" GO FROM "player100" OVER follow; +``` + +### 加载测试数据集 + +测试数据集名称为nba,详细Schema信息和数据信息请使用相关`SHOW`命令查看。 + +加载测试数据集命令如下: + +```ngql +nebula> :play nba +``` + +### 重复执行 -- 开启导出模式 +重复执行下一个命令N次,然后打印平均执行时间。命令如下: ```ngql -nebula> :SET CSV +nebula> :repeat N ``` -- 关闭导出模式 +示例: ```ngql -nebula> :UNSET CSV +nebula> :repeat 3 +nebula> GO FROM "player100" OVER follow; ++-------------+ +| follow._dst | ++-------------+ +| "player101" | ++-------------+ +| "player125" | ++-------------+ +Got 2 rows (time spent 2602/3214 us) + +Fri, 20 Aug 2021 06:36:05 UTC + ++-------------+ +| follow._dst | ++-------------+ +| "player101" | ++-------------+ +| "player125" | ++-------------+ +Got 2 rows (time spent 583/849 us) + +Fri, 20 Aug 2021 06:36:05 UTC + ++-------------+ +| follow._dst | ++-------------+ +| "player101" | ++-------------+ +| "player125" | ++-------------+ +Got 2 rows (time spent 496/671 us) + +Fri, 20 Aug 2021 06:36:05 UTC + +Executed 3 times, (total time spent 3681/4734 us), (average time spent 1227/1578 us) ``` -## 使用Nebula Console断开连接 +### 睡眠 + +睡眠N秒。常用于修改Schema的操作中,因为修改Schema是异步实现的,需要在下一个心跳周期才同步数据。命令如下: + +```ngql +nebula> :sleep N +``` + +### 断开连接 用户可以使用`:EXIT`或者`:QUIT`从Nebula Graph断开连接。为方便使用,Nebula Console支持使用不带冒号(:)的小写命令,例如`quit`。 +示例: + ```ngql nebula> :QUIT diff --git a/docs-2.0/reuse/source_install-nebula-graph-by-rpm-or-deb.md b/docs-2.0/reuse/source_install-nebula-graph-by-rpm-or-deb.md new file mode 100644 index 00000000000..a992f8acd92 --- /dev/null +++ b/docs-2.0/reuse/source_install-nebula-graph-by-rpm-or-deb.md @@ -0,0 +1,130 @@ +RPM和DEB是Linux系统下常见的两种安装包格式,本文介绍如何使用RPM或DEB文件在一台机器上快速安装Nebula Graph。 + +!!! note + + 部署Nebula Graph集群的方式参见[使用RPM/DEB包部署集群](/4.deployment-and-installation/2.compile-and-install-nebula-graph/deploy-nebula-graph-cluster)。 + +## 前提条件 + +安装wget + +## 下载安装包 + +### 阿里云OSS下载 + +- 下载release版本 + + URL格式如下: + + ```bash + //Centos 7 + https://oss-cdn.nebula-graph.com.cn/package//nebula-graph-.el7.x86_64.rpm + + //Centos 8 + https://oss-cdn.nebula-graph.com.cn/package//nebula-graph-.el8.x86_64.rpm + + //Ubuntu 1604 + https://oss-cdn.nebula-graph.com.cn/package//nebula-graph-.Ubuntu1604.amd64.deb + + //Ubuntu 1804 + https://oss-cdn.nebula-graph.com.cn/package//nebula-graph-.Ubuntu1804.amd64.deb + + //Ubuntu 2004 + https://oss-cdn.nebula-graph.com.cn/package//nebula-graph-.Ubuntu2004.amd64.deb + ``` + + 例如要下载适用于`Centos 7.5`的`{{ nebula.release }}`安装包: + + ```bash + wget https://oss-cdn.nebula-graph.com.cn/package/{{ nebula.release }}/nebula-graph-{{ nebula.release }}.el7.x86_64.rpm + wget https://oss-cdn.nebula-graph.com.cn/package/{{ nebula.release }}/nebula-graph-{{ nebula.release }}.el7.x86_64.rpm.sha256sum.txt + ``` + + 下载适用于`ubuntu 1804`的`{{ nebula.release }}`安装包: + ```bash + wget https://oss-cdn.nebula-graph.com.cn/package/{{ nebula.release }}/nebula-graph-{{ nebula.release }}.Ubuntu1804.amd64.deb + wget https://oss-cdn.nebula-graph.com.cn/package/{{ nebula.release }}/nebula-graph-{{ nebula.release }}.Ubuntu1804.amd64.deb.sha256sum.txt + ``` + +- 下载日常开发版本(nightly) + + !!! danger + + nightly版本通常用于测试新功能、新特性,请**不要**在生产环境中使用nightly版本。 + + URL格式如下: + + ```bash + //Centos 7 + https://oss-cdn.nebula-graph.com.cn/package/v2-nightly//nebula-graph--nightly.el7.x86_64.rpm + + //Centos 8 + https://oss-cdn.nebula-graph.com.cn/package/v2-nightly//nebula-graph--nightly.el8.x86_64.rpm + + //Ubuntu 1604 + https://oss-cdn.nebula-graph.com.cn/package/v2-nightly//nebula-graph--nightly.Ubuntu1604.amd64.deb + + //Ubuntu 1804 + https://oss-cdn.nebula-graph.com.cn/package/v2-nightly//nebula-graph--nightly.Ubuntu1804.amd64.deb + + //Ubuntu 2004 + https://oss-cdn.nebula-graph.com.cn/package/v2-nightly//nebula-graph--nightly.Ubuntu2004.amd64.deb + ``` + + 例如要下载`2021.08.18`适用于`Centos 7.5`的`2.x`安装包: + + ```bash + wget https://oss-cdn.nebula-graph.com.cn/package/v2-nightly/2021.08.18/nebula-graph-2021.08.18-nightly.el7.x86_64.rpm + wget https://oss-cdn.nebula-graph.com.cn/package/v2-nightly/2021.08.18/nebula-graph-2021.08.18-nightly.el7.x86_64.rpm.sha256sum.txt + ``` + + 要下载`2021.08.18`适用于`Ubuntu 1804`的`2.x`安装包: + ```bash + wget https://oss-cdn.nebula-graph.com.cn/package/v2-nightly/2021.08.18/nebula-graph-2021.08.18-nightly.Ubuntu1804.amd64.deb + wget https://oss-cdn.nebula-graph.com.cn/package/v2-nightly/2021.08.18/nebula-graph-2021.08.18-nightly.Ubuntu1804.amd64.deb.sha256sum.txt + ``` + + + +## 安装Nebula Graph + +- 安装RPM包 + + ```bash + $ sudo rpm -ivh --prefix= + ``` + +- 安装DEB包 + + ```bash + $ sudo dpkg -i --instdir== + ``` + +!!! Note + + 如果不设置安装路径,默认安装路径为`/usr/local/nebula/`。 + +## 后续操作 + +- [启动Nebula Graph](/4.deployment-and-installation/manage-service) +- [连接Nebula Graph](/2.quick-start/3.connect-to-nebula-graph) diff --git a/docs-2.0/reuse/source_manage-service.md b/docs-2.0/reuse/source_manage-service.md index 892757f015f..6dd8971f72a 100644 --- a/docs-2.0/reuse/source_manage-service.md +++ b/docs-2.0/reuse/source_manage-service.md @@ -46,7 +46,7 @@ $ sudo /usr/local/nebula/scripts/nebula.service start all 对于使用Docker Compose部署的Nebula Graph,在`nebula-docker-compose/`目录内执行如下命令启动服务: ```bash -nebula-docker-compose]$ docker-compose up -d +[nebula-docker-compose]$ docker-compose up -d Building with native build. Learn about native build in Compose here: https://docs.docker.com/go/compose-native-build/ Creating network "nebula-docker-compose_nebula-net" with the default driver Creating nebula-docker-compose_metad0_1 ... done @@ -185,4 +185,4 @@ nebula-docker-compose]$ docker exec -it 2a6c56c405f5 bash ## 下一步 -[连接Nebula Graph](../2.quick-start/3.connect-to-nebula-graph.md) \ No newline at end of file +[连接Nebula Graph](../2.quick-start/3.connect-to-nebula-graph.md) diff --git a/mkdocs.yml b/mkdocs.yml index 3cc970655ef..cca8cf0eaee 100755 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,4 +1,3 @@ -# Project information site_name: Nebula Graph Database 手册 site_description: Documentation for Nebula Graph Database site_author: Nebula Graph @@ -101,7 +100,7 @@ nav: - 快速入门: - 快速入门流程: 2.quick-start/1.quick-start-workflow.md - - 步骤1:安装Nebula Graph: 4.deployment-and-installation/2.compile-and-install-nebula-graph/2.install-nebula-graph-by-rpm-or-deb.md + - 步骤1:安装Nebula Graph: 2.quick-start/2.install-nebula-graph.md - 步骤2:启动Nebula Graph: 2.quick-start/5.start-stop-service.md - 步骤3:连接Nebula Graph: 2.quick-start/3.connect-to-nebula-graph.md - 步骤4:使用常用命令: 2.quick-start/4.nebula-graph-crud.md @@ -259,6 +258,7 @@ nav: - 使用Docker Compose部署: 4.deployment-and-installation/2.compile-and-install-nebula-graph/3.deploy-nebula-graph-with-docker-compose.md - 使用RPM/DEB包部署集群: 4.deployment-and-installation/2.compile-and-install-nebula-graph/deploy-nebula-graph-cluster.md - 管理服务: 4.deployment-and-installation/manage-service.md + - 连接服务: 4.deployment-and-installation/connect-to-nebula-graph.md - 升级版本: - 升级历史版本至v2.5.0: 4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-graph-to-250.md - 升级v2.0.x至v2.5.0: 4.deployment-and-installation/3.upgrade-nebula-graph/upgrade-nebula-from-200-to-250.md @@ -282,11 +282,11 @@ nav: - 身份验证: 7.data-security/1.authentication/1.authentication.md - 用户管理: 7.data-security/1.authentication/2.management-user.md - 内置角色权限: 7.data-security/1.authentication/3.role-list.md - - 备份恢复: - - 什么是BR: 7.data-security/2.backup-restore/1.what-is-br.md - - 编译BR: 7.data-security/2.backup-restore/2.compile-br.md - - 使用BR备份数据: 7.data-security/2.backup-restore/3.br-backup-data.md - - 使用BR恢复数据: 7.data-security/2.backup-restore/4.br-restore-data.md +# - 备份恢复: +# - 什么是BR: 7.data-security/2.backup-restore/1.what-is-br.md +# - 编译BR: 7.data-security/2.backup-restore/2.compile-br.md +# - 使用BR备份数据: 7.data-security/2.backup-restore/3.br-backup-data.md +# - 使用BR恢复数据: 7.data-security/2.backup-restore/4.br-restore-data.md - 管理快照: 7.data-security/3.manage-snapshot.md - 服务调优: @@ -383,6 +383,7 @@ nav: - 导入MaxCompute数据: nebula-exchange/use-exchange/ex-ug-import-from-maxcompute.md - 导入Pulsar数据: nebula-exchange/use-exchange/ex-ug-import-from-pulsar.md - 导入Kafka数据: nebula-exchange/use-exchange/ex-ug-import-from-kafka.md + - 导入SST文件数据: nebula-exchange/use-exchange/ex-ug-import-from-sst.md - Exchange 常见问题: nebula-exchange/ex-ug-FAQ.md - Nebula Algorithm: nebula-algorithm.md @@ -394,7 +395,8 @@ nav: - Nebula Bench: nebula-bench.md - 附录: - - Nebula Graph 常见问题: 20.appendix/0.FAQ.md + - Release Note: 20.appendix/releasenote.md + - 常见问题 FAQ: 20.appendix/0.FAQ.md - 生态工具概览: 20.appendix/6.eco-tool-version.md - 导入工具选择: 20.appendix/write-tools.md - 社区参与: 15.contribution/how-to-contribute.md @@ -422,11 +424,12 @@ markdown_extensions: # Plugins plugins: - search - - macros + - macros: + include_dir: docs-2.0/reuse/ - git-revision-date-localized - with-pdf: copyright: 2021 Vesoft Inc. - cover_subtitle: 2.5.0 + cover_subtitle: master since v2.5.0 author: 吴敏,周瑶,梁振亚,杨怡璇 cover: true back_cover: true diff --git a/overrides/partials/header.html b/overrides/partials/header.html index c6443709a9b..023ed66359f 100644 --- a/overrides/partials/header.html +++ b/overrides/partials/header.html @@ -1,100 +1,100 @@ {#- - This file was automatically generated - do not edit --#} -

-
- -