From 723c092072cf5727990b08d5d3840c1a14599173 Mon Sep 17 00:00:00 2001 From: Stefano Ottolenghi Date: Tue, 23 Jul 2024 11:23:06 +0200 Subject: [PATCH 01/20] Update version to 5.23. --- antora.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/antora.yml b/antora.yml index 986c4d003..3efd4c638 100644 --- a/antora.yml +++ b/antora.yml @@ -7,5 +7,5 @@ nav: asciidoc: attributes: neo4j-version: '5' - neo4j-version-minor: '5.22' - neo4j-version-exact: '5.22.0' + neo4j-version-minor: '5.23' + neo4j-version-exact: '5.23.0' From 87a4ebfa980a9da039534375cbbfa199cc66ded9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 10:04:34 +0200 Subject: [PATCH 02/20] Bump the prod-dependencies group with 2 updates (#1001) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the prod-dependencies group with 2 updates: [@antora/cli](https://gitlab.com/antora/antora) and [@antora/site-generator-default](https://gitlab.com/antora/antora). Updates `@antora/cli` from 3.1.8 to 3.1.9
Changelog

Sourced from @​antora/cli's changelog.

== 3.1.9 (2024-07-05)

=== Changed

  • site-generator: Detect and warn when an AsciiDoc extension is registered as an Antora extension, but do no skip it (#1141)
  • Replace "AsciiDoc extension" with "Asciidoctor extension" in log messages

=== Fixed

  • file-publisher: Wrap legacy stream on file when preparing files for output providers; remove listeners limit (#1139)
Commits

Updates `@antora/site-generator-default` from 3.1.8 to 3.1.9
Changelog

Sourced from @​antora/site-generator-default's changelog.

== 3.1.9 (2024-07-05)

=== Changed

  • site-generator: Detect and warn when an AsciiDoc extension is registered as an Antora extension, but do no skip it (#1141)
  • Replace "AsciiDoc extension" with "Asciidoctor extension" in log messages

=== Fixed

  • file-publisher: Wrap legacy stream on file when preparing files for output providers; remove listeners limit (#1139)
Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 320 +++++++++++++++++++++++----------------------- package.json | 4 +- 2 files changed, 162 insertions(+), 162 deletions(-) diff --git a/package-lock.json b/package-lock.json index 74567389f..73be5181f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "5.0.0", "license": "ISC", "dependencies": { - "@antora/cli": "^3.1.8", - "@antora/site-generator-default": "^3.1.8", + "@antora/cli": "^3.1.9", + "@antora/site-generator-default": "^3.1.9", "@neo4j-antora/antora-add-notes": "^0.3.1", "@neo4j-antora/antora-modify-sitemaps": "^0.4.4", "@neo4j-antora/antora-page-roles": "^0.3.1", @@ -26,11 +26,11 @@ } }, "node_modules/@antora/asciidoc-loader": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/asciidoc-loader/-/asciidoc-loader-3.1.8.tgz", - "integrity": "sha512-tNa9YBA/wVA3RGmDhAF2i4s7TPWgMcZsKZF1+mFBiYmhVuIiI5mkp6sH2M+/8MlApydSOc8p375gudgLKPKrJw==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/asciidoc-loader/-/asciidoc-loader-3.1.9.tgz", + "integrity": "sha512-flE27T2yI8TX7rUNjbBHWN3iR6s+kBuRBbUPncUFcWjx6mXzll8JLiTkxnc8JXHGzgKlveT+t5AkPYGACLfasg==", "dependencies": { - "@antora/logger": "3.1.8", + "@antora/logger": "3.1.9", "@antora/user-require-helper": "~2.0", "@asciidoctor/core": "~2.2" }, @@ -39,12 +39,12 @@ } }, "node_modules/@antora/cli": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/cli/-/cli-3.1.8.tgz", - "integrity": "sha512-V7oIbbAONovCQWX2tKG14YmX03p6tquLP753NJEjj7QXjiWmJhOI0JsTD+fvaXr7DzkDnjnls4OwFBmiHZIkOw==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/cli/-/cli-3.1.9.tgz", + "integrity": "sha512-kCUqWX3G/9Pvf8SWZ45ioHwWdOc9uamy2E5/FFwyGiTeu4ubNbadOauLVvMzSZHUxVDnGxXwCsmmQ2HwM919ew==", "dependencies": { - "@antora/logger": "3.1.8", - "@antora/playbook-builder": "3.1.8", + "@antora/logger": "3.1.9", + "@antora/playbook-builder": "3.1.9", "@antora/user-require-helper": "~2.0", "commander": "~11.1" }, @@ -56,12 +56,12 @@ } }, "node_modules/@antora/content-aggregator": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/content-aggregator/-/content-aggregator-3.1.8.tgz", - "integrity": "sha512-xBWbw2fiQ6UMEIGzknvpDLUW0gTpyiQVaRXjAOYe0JDAAvifjt0uJuBsu7WrRe1FmRkfkrYj8BJ6Yv34NWZJuA==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/content-aggregator/-/content-aggregator-3.1.9.tgz", + "integrity": "sha512-g+UzevPSm5c4R0j1U9uysJfdIUfp++QOHIEBmqjhfx/aIEnOL70zA+WF55Mm+syAfzU3877puI27sOp8qtPglw==", "dependencies": { "@antora/expand-path-helper": "~2.0", - "@antora/logger": "3.1.8", + "@antora/logger": "3.1.9", "@antora/user-require-helper": "~2.0", "braces": "~3.0", "cache-directory": "~2.0", @@ -92,12 +92,12 @@ } }, "node_modules/@antora/content-classifier": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/content-classifier/-/content-classifier-3.1.8.tgz", - "integrity": "sha512-0EzsZl7oBR5/MzLGIo3WwFeub2YtyDqExrELDmyDcJ4opZMREWfgUFu5Kls1MFAQPSbzEmQyIdyGacOrwTQHrg==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/content-classifier/-/content-classifier-3.1.9.tgz", + "integrity": "sha512-PVJqwp5uvZE1PlpeJtb0p6al75fN+fmXGIC6DHcKysRnr0xo+sgz8X2r4mnNWdTWRqum2yVigMmmuXYTg3cJlQ==", "dependencies": { - "@antora/asciidoc-loader": "3.1.8", - "@antora/logger": "3.1.8", + "@antora/asciidoc-loader": "3.1.9", + "@antora/logger": "3.1.9", "mime-types": "~2.1", "vinyl": "~3.0" }, @@ -106,11 +106,11 @@ } }, "node_modules/@antora/document-converter": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/document-converter/-/document-converter-3.1.8.tgz", - "integrity": "sha512-dUGqgSdWnJYigbPZ9mDcoxITnufOEF5Vb5DKUxEstXe6MMn0yTZ03jJUbLs5YFgjqjhyULDMMIPo6no55zvx+w==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/document-converter/-/document-converter-3.1.9.tgz", + "integrity": "sha512-pH7tQaIjcPsFdYkaBEAvA/5ki04IQwQGHoR+2jadKdMl6P+J5KA1VzNnMgyIL6gHn7auJIkoOKadfItRB9lHGQ==", "dependencies": { - "@antora/asciidoc-loader": "3.1.8" + "@antora/asciidoc-loader": "3.1.9" }, "engines": { "node": ">=16.0.0" @@ -125,9 +125,9 @@ } }, "node_modules/@antora/file-publisher": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/file-publisher/-/file-publisher-3.1.8.tgz", - "integrity": "sha512-crVP9EF5NZJDzeYPSpy74x35GRJIa4PfjfYBUxhzoNfqgX3JZcNuP8IwsWrSNyBDGO9a7ZCQ7+p4kpnVpF2x8Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/file-publisher/-/file-publisher-3.1.9.tgz", + "integrity": "sha512-C0VwVjuFbE1CVpZDgwYR1gZCNr1tMw5vueyF9wHZH0KCqAsp9iwo7bwj8wKWMPogxcxdYhnAvtDJnYmYFCuDWQ==", "dependencies": { "@antora/expand-path-helper": "~2.0", "@antora/user-require-helper": "~2.0", @@ -139,9 +139,9 @@ } }, "node_modules/@antora/logger": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/logger/-/logger-3.1.8.tgz", - "integrity": "sha512-zbfjB1oMDDuuHjiRnBIbVTUBW1l1hCHbK4Q1oIRujnSz2LLjyY/aZfvgwODpREBGmvjkFb6Dlc9VUkKObQKi7g==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/logger/-/logger-3.1.9.tgz", + "integrity": "sha512-MKuANodcX0lfRyiB+Rxl/Kv7UOxc2glzTYFoIoBB7uzxF0A+AhvUJDmpGQFRFN2ihxy99N3nLJmZpDebwXyE+A==", "dependencies": { "@antora/expand-path-helper": "~2.0", "pino": "~9.2", @@ -153,22 +153,22 @@ } }, "node_modules/@antora/navigation-builder": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/navigation-builder/-/navigation-builder-3.1.8.tgz", - "integrity": "sha512-u/USiJ1HhKSUxfUtLv7aQBFCJfBz6RtdzapKIy4z2Wol0FrwQwdaUhv7Amzabi2nrPEzkaNAM6ZX7iNPjGOw6Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/navigation-builder/-/navigation-builder-3.1.9.tgz", + "integrity": "sha512-zyl2yNjK31Dl6TRJgnoFb4Czwt9ar3wLTycAdMeZ+U/8YcAUHD8z7NCssPFFvZ0BbUr00NP+gbqDmCr6yz32NQ==", "dependencies": { - "@antora/asciidoc-loader": "3.1.8" + "@antora/asciidoc-loader": "3.1.9" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@antora/page-composer": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/page-composer/-/page-composer-3.1.8.tgz", - "integrity": "sha512-dw1ECMLYdf9GC9Zj8sHPd9Fgcg6BjU5BDbP+HI4omtOhLUiBVwWL1lZwFRVwgGMDgKSVgnxd9yotk+WTy2iLEg==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/page-composer/-/page-composer-3.1.9.tgz", + "integrity": "sha512-X6Qj+J5dfFAGXoCAOaA+R6xRp8UoNMDHsRsB1dUTT2QNzk1Lrq6YkYyljdD2cxkWjLVqQ/pQSP+BJVNFGbqDAQ==", "dependencies": { - "@antora/logger": "3.1.8", + "@antora/logger": "3.1.9", "handlebars": "~4.7", "require-from-string": "~2.0" }, @@ -177,9 +177,9 @@ } }, "node_modules/@antora/playbook-builder": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/playbook-builder/-/playbook-builder-3.1.8.tgz", - "integrity": "sha512-VDIP8cVnmyRcbg4orP2mE8HkqHTh7MRE+QyJ8XyHvFZsZjcS0Qw5UqPcrlmqXrzQKmJcBj2plqSv+wKXAYbNcQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/playbook-builder/-/playbook-builder-3.1.9.tgz", + "integrity": "sha512-MJ/OWz4pReC98nygGTXC5bOL/TDDtCYpSkHFBz2ST4L6tuM8rv9c5+cp//JkwY/QlTOvcuJ0f2xq4a7a5nI7Qw==", "dependencies": { "@iarna/toml": "~2.2", "convict": "~6.2", @@ -191,9 +191,9 @@ } }, "node_modules/@antora/redirect-producer": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/redirect-producer/-/redirect-producer-3.1.8.tgz", - "integrity": "sha512-ZSRnK/rXZ715baFheXMWEsyz0BpR+6RxFAem8A7rZPt2HMMKCOiuaFNdf9C97dxU5FxSELBIkRpqQ7eTRk+PPA==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/redirect-producer/-/redirect-producer-3.1.9.tgz", + "integrity": "sha512-9OLwoMhqifsBxTebInh/5W16GdDsdj+YkKG3TiCASlAOYsDbuhbeRPFUlyKKSRkMrtKKnFgHR0Z3DNPXYlH2NQ==", "dependencies": { "vinyl": "~3.0" }, @@ -202,23 +202,23 @@ } }, "node_modules/@antora/site-generator": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/site-generator/-/site-generator-3.1.8.tgz", - "integrity": "sha512-xy1aUxTsCiC/KPlKQIoj2VWK956Mal8YyeokqXQTlTfRkuT5LPTJdmTA1ZHMEY9INy0z01Jx56Uyns62q98UtQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/site-generator/-/site-generator-3.1.9.tgz", + "integrity": "sha512-YYESPG22tGX1CxRPSAr6acKILCO8JfGkM1OYc7Sw3D7ZvCy1YgZMAaTYK0T5yl9LXg+l/UZi1xq/Ej0qHnYQiw==", "dependencies": { - "@antora/asciidoc-loader": "3.1.8", - "@antora/content-aggregator": "3.1.8", - "@antora/content-classifier": "3.1.8", - "@antora/document-converter": "3.1.8", - "@antora/file-publisher": "3.1.8", - "@antora/logger": "3.1.8", - "@antora/navigation-builder": "3.1.8", - "@antora/page-composer": "3.1.8", - "@antora/playbook-builder": "3.1.8", - "@antora/redirect-producer": "3.1.8", - "@antora/site-mapper": "3.1.8", - "@antora/site-publisher": "3.1.8", - "@antora/ui-loader": "3.1.8", + "@antora/asciidoc-loader": "3.1.9", + "@antora/content-aggregator": "3.1.9", + "@antora/content-classifier": "3.1.9", + "@antora/document-converter": "3.1.9", + "@antora/file-publisher": "3.1.9", + "@antora/logger": "3.1.9", + "@antora/navigation-builder": "3.1.9", + "@antora/page-composer": "3.1.9", + "@antora/playbook-builder": "3.1.9", + "@antora/redirect-producer": "3.1.9", + "@antora/site-mapper": "3.1.9", + "@antora/site-publisher": "3.1.9", + "@antora/ui-loader": "3.1.9", "@antora/user-require-helper": "~2.0" }, "engines": { @@ -226,22 +226,22 @@ } }, "node_modules/@antora/site-generator-default": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/site-generator-default/-/site-generator-default-3.1.8.tgz", - "integrity": "sha512-6cjgxatANsp4iTbX6gbadfWwYngH4EXG3AyFWOmf6jMRih2MQSGc9zYL+QfHP6uqUiBfhIPCFwLbh3IiQ1v8JQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/site-generator-default/-/site-generator-default-3.1.9.tgz", + "integrity": "sha512-m/QCv2o/24VmWZaeqtc6nNEky///GTLLx/pyyihP7uWKvZ0AhGPp6Agv1yaShjKIthBzHJ3JozaMPev2leor+A==", "dependencies": { - "@antora/site-generator": "3.1.8" + "@antora/site-generator": "3.1.9" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@antora/site-mapper": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/site-mapper/-/site-mapper-3.1.8.tgz", - "integrity": "sha512-RV6SRiNFDd/dQRXvsckTsFQIiEpH7rHIoKlsOFB261rRY4JhXSu21TjR0dpk2vJ6iPMyudIuTkwoTWsdDi389Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/site-mapper/-/site-mapper-3.1.9.tgz", + "integrity": "sha512-9FCObL+JIjBoby8z+beu2uuvAtCjm5EsEQt+16gCIMX1ktVP3W3gVsdRSvVcGcVEpizILFhMawkcQknZPUp5mg==", "dependencies": { - "@antora/content-classifier": "3.1.8", + "@antora/content-classifier": "3.1.9", "vinyl": "~3.0" }, "engines": { @@ -249,20 +249,20 @@ } }, "node_modules/@antora/site-publisher": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/site-publisher/-/site-publisher-3.1.8.tgz", - "integrity": "sha512-DdC+IDdzeYlmTu+LwMZ24hFJJRU+f8WG2MjM7kvKQ8fkPdk0TdzNoq3TkH78sYd+2WYXKuQU6DFU/OPxY44ulA==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/site-publisher/-/site-publisher-3.1.9.tgz", + "integrity": "sha512-L5To8f4QswZliXu6yB6O7O8CuBbLctjNbxZqP3m0FP7VaOONp85ftzEq1BFEm4BXXSwH1n4ujZx1qGBHP9ooOQ==", "dependencies": { - "@antora/file-publisher": "3.1.8" + "@antora/file-publisher": "3.1.9" }, "engines": { "node": ">=16.0.0" } }, "node_modules/@antora/ui-loader": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/ui-loader/-/ui-loader-3.1.8.tgz", - "integrity": "sha512-wiStSKnt+QGTeVRpnM9fxOUf1xxyB4Y3cgRgdi5hb291pG/izz8imh3csjgMwN2jB3zZD4qYSJ29xnGr4+pK8Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/ui-loader/-/ui-loader-3.1.9.tgz", + "integrity": "sha512-g0/9dRE5JVMYukIU3x+Rvr41bPdK3sUD2xQIAniRjE6usIZs1mEsTGshVKVEoOqqnSekXE85HVhybjNHsC+qbQ==", "dependencies": { "@antora/expand-path-helper": "~2.0", "braces": "~3.0", @@ -2354,9 +2354,9 @@ } }, "node_modules/text-decoder": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", - "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", + "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", "dependencies": { "b4a": "^1.6.4" } @@ -2415,9 +2415,9 @@ } }, "node_modules/uglify-js": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", - "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", + "version": "3.19.1", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.1.tgz", + "integrity": "sha512-y/2wiW+ceTYR2TSSptAhfnEtpLaQ4Ups5zrjB2d3kuVxHj16j/QJwPl5PvuGy9uARb39J0+iKxcRPvtpsx4A4A==", "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -2542,33 +2542,33 @@ }, "dependencies": { "@antora/asciidoc-loader": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/asciidoc-loader/-/asciidoc-loader-3.1.8.tgz", - "integrity": "sha512-tNa9YBA/wVA3RGmDhAF2i4s7TPWgMcZsKZF1+mFBiYmhVuIiI5mkp6sH2M+/8MlApydSOc8p375gudgLKPKrJw==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/asciidoc-loader/-/asciidoc-loader-3.1.9.tgz", + "integrity": "sha512-flE27T2yI8TX7rUNjbBHWN3iR6s+kBuRBbUPncUFcWjx6mXzll8JLiTkxnc8JXHGzgKlveT+t5AkPYGACLfasg==", "requires": { - "@antora/logger": "3.1.8", + "@antora/logger": "3.1.9", "@antora/user-require-helper": "~2.0", "@asciidoctor/core": "~2.2" } }, "@antora/cli": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/cli/-/cli-3.1.8.tgz", - "integrity": "sha512-V7oIbbAONovCQWX2tKG14YmX03p6tquLP753NJEjj7QXjiWmJhOI0JsTD+fvaXr7DzkDnjnls4OwFBmiHZIkOw==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/cli/-/cli-3.1.9.tgz", + "integrity": "sha512-kCUqWX3G/9Pvf8SWZ45ioHwWdOc9uamy2E5/FFwyGiTeu4ubNbadOauLVvMzSZHUxVDnGxXwCsmmQ2HwM919ew==", "requires": { - "@antora/logger": "3.1.8", - "@antora/playbook-builder": "3.1.8", + "@antora/logger": "3.1.9", + "@antora/playbook-builder": "3.1.9", "@antora/user-require-helper": "~2.0", "commander": "~11.1" } }, "@antora/content-aggregator": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/content-aggregator/-/content-aggregator-3.1.8.tgz", - "integrity": "sha512-xBWbw2fiQ6UMEIGzknvpDLUW0gTpyiQVaRXjAOYe0JDAAvifjt0uJuBsu7WrRe1FmRkfkrYj8BJ6Yv34NWZJuA==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/content-aggregator/-/content-aggregator-3.1.9.tgz", + "integrity": "sha512-g+UzevPSm5c4R0j1U9uysJfdIUfp++QOHIEBmqjhfx/aIEnOL70zA+WF55Mm+syAfzU3877puI27sOp8qtPglw==", "requires": { "@antora/expand-path-helper": "~2.0", - "@antora/logger": "3.1.8", + "@antora/logger": "3.1.9", "@antora/user-require-helper": "~2.0", "braces": "~3.0", "cache-directory": "~2.0", @@ -2592,22 +2592,22 @@ } }, "@antora/content-classifier": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/content-classifier/-/content-classifier-3.1.8.tgz", - "integrity": "sha512-0EzsZl7oBR5/MzLGIo3WwFeub2YtyDqExrELDmyDcJ4opZMREWfgUFu5Kls1MFAQPSbzEmQyIdyGacOrwTQHrg==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/content-classifier/-/content-classifier-3.1.9.tgz", + "integrity": "sha512-PVJqwp5uvZE1PlpeJtb0p6al75fN+fmXGIC6DHcKysRnr0xo+sgz8X2r4mnNWdTWRqum2yVigMmmuXYTg3cJlQ==", "requires": { - "@antora/asciidoc-loader": "3.1.8", - "@antora/logger": "3.1.8", + "@antora/asciidoc-loader": "3.1.9", + "@antora/logger": "3.1.9", "mime-types": "~2.1", "vinyl": "~3.0" } }, "@antora/document-converter": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/document-converter/-/document-converter-3.1.8.tgz", - "integrity": "sha512-dUGqgSdWnJYigbPZ9mDcoxITnufOEF5Vb5DKUxEstXe6MMn0yTZ03jJUbLs5YFgjqjhyULDMMIPo6no55zvx+w==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/document-converter/-/document-converter-3.1.9.tgz", + "integrity": "sha512-pH7tQaIjcPsFdYkaBEAvA/5ki04IQwQGHoR+2jadKdMl6P+J5KA1VzNnMgyIL6gHn7auJIkoOKadfItRB9lHGQ==", "requires": { - "@antora/asciidoc-loader": "3.1.8" + "@antora/asciidoc-loader": "3.1.9" } }, "@antora/expand-path-helper": { @@ -2616,9 +2616,9 @@ "integrity": "sha512-CSMBGC+tI21VS2kGW3PV7T2kQTM5eT3f2GTPVLttwaNYbNxDve08en/huzszHJfxo11CcEs26Ostr0F2c1QqeA==" }, "@antora/file-publisher": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/file-publisher/-/file-publisher-3.1.8.tgz", - "integrity": "sha512-crVP9EF5NZJDzeYPSpy74x35GRJIa4PfjfYBUxhzoNfqgX3JZcNuP8IwsWrSNyBDGO9a7ZCQ7+p4kpnVpF2x8Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/file-publisher/-/file-publisher-3.1.9.tgz", + "integrity": "sha512-C0VwVjuFbE1CVpZDgwYR1gZCNr1tMw5vueyF9wHZH0KCqAsp9iwo7bwj8wKWMPogxcxdYhnAvtDJnYmYFCuDWQ==", "requires": { "@antora/expand-path-helper": "~2.0", "@antora/user-require-helper": "~2.0", @@ -2627,9 +2627,9 @@ } }, "@antora/logger": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/logger/-/logger-3.1.8.tgz", - "integrity": "sha512-zbfjB1oMDDuuHjiRnBIbVTUBW1l1hCHbK4Q1oIRujnSz2LLjyY/aZfvgwODpREBGmvjkFb6Dlc9VUkKObQKi7g==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/logger/-/logger-3.1.9.tgz", + "integrity": "sha512-MKuANodcX0lfRyiB+Rxl/Kv7UOxc2glzTYFoIoBB7uzxF0A+AhvUJDmpGQFRFN2ihxy99N3nLJmZpDebwXyE+A==", "requires": { "@antora/expand-path-helper": "~2.0", "pino": "~9.2", @@ -2638,27 +2638,27 @@ } }, "@antora/navigation-builder": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/navigation-builder/-/navigation-builder-3.1.8.tgz", - "integrity": "sha512-u/USiJ1HhKSUxfUtLv7aQBFCJfBz6RtdzapKIy4z2Wol0FrwQwdaUhv7Amzabi2nrPEzkaNAM6ZX7iNPjGOw6Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/navigation-builder/-/navigation-builder-3.1.9.tgz", + "integrity": "sha512-zyl2yNjK31Dl6TRJgnoFb4Czwt9ar3wLTycAdMeZ+U/8YcAUHD8z7NCssPFFvZ0BbUr00NP+gbqDmCr6yz32NQ==", "requires": { - "@antora/asciidoc-loader": "3.1.8" + "@antora/asciidoc-loader": "3.1.9" } }, "@antora/page-composer": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/page-composer/-/page-composer-3.1.8.tgz", - "integrity": "sha512-dw1ECMLYdf9GC9Zj8sHPd9Fgcg6BjU5BDbP+HI4omtOhLUiBVwWL1lZwFRVwgGMDgKSVgnxd9yotk+WTy2iLEg==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/page-composer/-/page-composer-3.1.9.tgz", + "integrity": "sha512-X6Qj+J5dfFAGXoCAOaA+R6xRp8UoNMDHsRsB1dUTT2QNzk1Lrq6YkYyljdD2cxkWjLVqQ/pQSP+BJVNFGbqDAQ==", "requires": { - "@antora/logger": "3.1.8", + "@antora/logger": "3.1.9", "handlebars": "~4.7", "require-from-string": "~2.0" } }, "@antora/playbook-builder": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/playbook-builder/-/playbook-builder-3.1.8.tgz", - "integrity": "sha512-VDIP8cVnmyRcbg4orP2mE8HkqHTh7MRE+QyJ8XyHvFZsZjcS0Qw5UqPcrlmqXrzQKmJcBj2plqSv+wKXAYbNcQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/playbook-builder/-/playbook-builder-3.1.9.tgz", + "integrity": "sha512-MJ/OWz4pReC98nygGTXC5bOL/TDDtCYpSkHFBz2ST4L6tuM8rv9c5+cp//JkwY/QlTOvcuJ0f2xq4a7a5nI7Qw==", "requires": { "@iarna/toml": "~2.2", "convict": "~6.2", @@ -2667,63 +2667,63 @@ } }, "@antora/redirect-producer": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/redirect-producer/-/redirect-producer-3.1.8.tgz", - "integrity": "sha512-ZSRnK/rXZ715baFheXMWEsyz0BpR+6RxFAem8A7rZPt2HMMKCOiuaFNdf9C97dxU5FxSELBIkRpqQ7eTRk+PPA==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/redirect-producer/-/redirect-producer-3.1.9.tgz", + "integrity": "sha512-9OLwoMhqifsBxTebInh/5W16GdDsdj+YkKG3TiCASlAOYsDbuhbeRPFUlyKKSRkMrtKKnFgHR0Z3DNPXYlH2NQ==", "requires": { "vinyl": "~3.0" } }, "@antora/site-generator": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/site-generator/-/site-generator-3.1.8.tgz", - "integrity": "sha512-xy1aUxTsCiC/KPlKQIoj2VWK956Mal8YyeokqXQTlTfRkuT5LPTJdmTA1ZHMEY9INy0z01Jx56Uyns62q98UtQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/site-generator/-/site-generator-3.1.9.tgz", + "integrity": "sha512-YYESPG22tGX1CxRPSAr6acKILCO8JfGkM1OYc7Sw3D7ZvCy1YgZMAaTYK0T5yl9LXg+l/UZi1xq/Ej0qHnYQiw==", "requires": { - "@antora/asciidoc-loader": "3.1.8", - "@antora/content-aggregator": "3.1.8", - "@antora/content-classifier": "3.1.8", - "@antora/document-converter": "3.1.8", - "@antora/file-publisher": "3.1.8", - "@antora/logger": "3.1.8", - "@antora/navigation-builder": "3.1.8", - "@antora/page-composer": "3.1.8", - "@antora/playbook-builder": "3.1.8", - "@antora/redirect-producer": "3.1.8", - "@antora/site-mapper": "3.1.8", - "@antora/site-publisher": "3.1.8", - "@antora/ui-loader": "3.1.8", + "@antora/asciidoc-loader": "3.1.9", + "@antora/content-aggregator": "3.1.9", + "@antora/content-classifier": "3.1.9", + "@antora/document-converter": "3.1.9", + "@antora/file-publisher": "3.1.9", + "@antora/logger": "3.1.9", + "@antora/navigation-builder": "3.1.9", + "@antora/page-composer": "3.1.9", + "@antora/playbook-builder": "3.1.9", + "@antora/redirect-producer": "3.1.9", + "@antora/site-mapper": "3.1.9", + "@antora/site-publisher": "3.1.9", + "@antora/ui-loader": "3.1.9", "@antora/user-require-helper": "~2.0" } }, "@antora/site-generator-default": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/site-generator-default/-/site-generator-default-3.1.8.tgz", - "integrity": "sha512-6cjgxatANsp4iTbX6gbadfWwYngH4EXG3AyFWOmf6jMRih2MQSGc9zYL+QfHP6uqUiBfhIPCFwLbh3IiQ1v8JQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/site-generator-default/-/site-generator-default-3.1.9.tgz", + "integrity": "sha512-m/QCv2o/24VmWZaeqtc6nNEky///GTLLx/pyyihP7uWKvZ0AhGPp6Agv1yaShjKIthBzHJ3JozaMPev2leor+A==", "requires": { - "@antora/site-generator": "3.1.8" + "@antora/site-generator": "3.1.9" } }, "@antora/site-mapper": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/site-mapper/-/site-mapper-3.1.8.tgz", - "integrity": "sha512-RV6SRiNFDd/dQRXvsckTsFQIiEpH7rHIoKlsOFB261rRY4JhXSu21TjR0dpk2vJ6iPMyudIuTkwoTWsdDi389Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/site-mapper/-/site-mapper-3.1.9.tgz", + "integrity": "sha512-9FCObL+JIjBoby8z+beu2uuvAtCjm5EsEQt+16gCIMX1ktVP3W3gVsdRSvVcGcVEpizILFhMawkcQknZPUp5mg==", "requires": { - "@antora/content-classifier": "3.1.8", + "@antora/content-classifier": "3.1.9", "vinyl": "~3.0" } }, "@antora/site-publisher": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/site-publisher/-/site-publisher-3.1.8.tgz", - "integrity": "sha512-DdC+IDdzeYlmTu+LwMZ24hFJJRU+f8WG2MjM7kvKQ8fkPdk0TdzNoq3TkH78sYd+2WYXKuQU6DFU/OPxY44ulA==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/site-publisher/-/site-publisher-3.1.9.tgz", + "integrity": "sha512-L5To8f4QswZliXu6yB6O7O8CuBbLctjNbxZqP3m0FP7VaOONp85ftzEq1BFEm4BXXSwH1n4ujZx1qGBHP9ooOQ==", "requires": { - "@antora/file-publisher": "3.1.8" + "@antora/file-publisher": "3.1.9" } }, "@antora/ui-loader": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@antora/ui-loader/-/ui-loader-3.1.8.tgz", - "integrity": "sha512-wiStSKnt+QGTeVRpnM9fxOUf1xxyB4Y3cgRgdi5hb291pG/izz8imh3csjgMwN2jB3zZD4qYSJ29xnGr4+pK8Q==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@antora/ui-loader/-/ui-loader-3.1.9.tgz", + "integrity": "sha512-g0/9dRE5JVMYukIU3x+Rvr41bPdK3sUD2xQIAniRjE6usIZs1mEsTGshVKVEoOqqnSekXE85HVhybjNHsC+qbQ==", "requires": { "@antora/expand-path-helper": "~2.0", "braces": "~3.0", @@ -4240,9 +4240,9 @@ } }, "text-decoder": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", - "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", + "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", "requires": { "b4a": "^1.6.4" } @@ -4289,9 +4289,9 @@ } }, "uglify-js": { - "version": "3.18.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", - "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", + "version": "3.19.1", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.1.tgz", + "integrity": "sha512-y/2wiW+ceTYR2TSSptAhfnEtpLaQ4Ups5zrjB2d3kuVxHj16j/QJwPl5PvuGy9uARb39J0+iKxcRPvtpsx4A4A==", "optional": true }, "undefsafe": { diff --git a/package.json b/package.json index 9bcea5a76..624ebb8c1 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "author": "Neo4j", "license": "ISC", "dependencies": { - "@antora/cli": "^3.1.8", - "@antora/site-generator-default": "^3.1.8", + "@antora/cli": "^3.1.9", + "@antora/site-generator-default": "^3.1.9", "@neo4j-antora/antora-add-notes": "^0.3.1", "@neo4j-antora/antora-modify-sitemaps": "^0.4.4", "@neo4j-antora/antora-page-roles": "^0.3.1", From 5af21500e41ecc25ea178d41fc004998b255dd0d Mon Sep 17 00:00:00 2001 From: Gem Lamont <106068376+gem-neo4j@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:24:57 +0200 Subject: [PATCH 03/20] Add TIME ZONE alias (#1010) GQL additionally allows for TIME ZONE (Not TIMEZONE like we currently have) --- .../pages/appendix/gql-conformance/index.adoc | 2 +- ...ions-additions-removals-compatibility.adoc | 23 +++++++++++++++++++ .../property-structural-constructed.adoc | 8 +++---- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/modules/ROOT/pages/appendix/gql-conformance/index.adoc b/modules/ROOT/pages/appendix/gql-conformance/index.adoc index 4c4da7984..2bc52908d 100644 --- a/modules/ROOT/pages/appendix/gql-conformance/index.adoc +++ b/modules/ROOT/pages/appendix/gql-conformance/index.adoc @@ -42,5 +42,5 @@ Neo4j 5.14 added support for JavaSE 21 and version 15 of the Unicode Standard. For more information, see xref:syntax/parsing.adoc##_using_unicodes_in_cypher[Parsing -> Using Unicode in Cypher]. * Cypher supports the following mandatory GQL property types: `BOOLEAN` (`BOOL`), `FLOAT` footnote:[The `FLOAT` type in Cypher always represents a 64-bit double-precision floating point number.], `INTEGER` (`SIGNED INTEGER`, or `INT`)footnote:[The `INTEGER` type in Cypher always represents a 64-bit `INTEGER`.], and `STRING` (`VARCHAR`). + -Cypher also supports the following optional GQL property types: `DATE`, `DURATION`, `LIST` (`ARRAY`, `INNER_TYPE LIST`, or `INNER_TYPE ARRAY`)footnote:[The `INNER_TYPE` cannot be a `LIST` type.], `LOCAL DATETIME` (`TIMESTAMP WITHOUT TIMEZONE`), `LOCAL TIME` (`TIME WITHOUT TIME ZONE`), `POINT`, `ZONED DATETIME` (`TIME WITH TIMEZONE`), and `ZONED TIME` (`TIMESTAMP WITH TIMEZONE`). +Cypher also supports the following optional GQL property types: `DATE`, `DURATION`, `LIST` (`ARRAY`, `INNER_TYPE LIST`, or `INNER_TYPE ARRAY`)footnote:[The `INNER_TYPE` cannot be a `LIST` type.], `LOCAL DATETIME` (`TIMESTAMP WITHOUT TIME ZONE`), `LOCAL TIME` (`TIME WITHOUT TIME ZONE`), `POINT`, `ZONED DATETIME` (`TIME WITH TIME ZONE`), and `ZONED TIME` (`TIMESTAMP WITH TIME ZONE`). For more information, see xref:values-and-types/property-structural-constructed.adoc#_property_types[Values and types -> property types]. diff --git a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc index a815e56db..62109c01f 100644 --- a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc +++ b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc @@ -16,6 +16,29 @@ New features are added to the language continuously, and occasionally, some feat This section lists all of the features that have been removed, deprecated, added, or extended in different Cypher versions. Replacement syntax for deprecated and removed features are also indicated. +[[cypher-deprecations-additions-removals-5.23]] +== Neo4j 5.23 + +=== Updated features + +[cols="2", options="header"] +|=== +| Feature +| Details + +a| +label:functionality[] +label:updated[] +[source, cypher, role="noheader"] +---- +RETURN datetime.statement() IS :: TIMESTAMP WITH TIME ZONE +---- +a| +Introduced new GQL conformant aliases to duration types: `TIMESTAMP WITHOUT TIME ZONE` (alias to `LOCAL DATETIME`), `TIME WITHOUT TIME ZONE` (alias to `LOCAL TIME`), `TIMESTAMP WITH TIME ZONE` (alias to `ZONED DATETIME`), and `TIME WITH TIME ZONE` (alias to `ZONED TIME`). + +See xref::values-and-types/property-structural-constructed.adoc#types-synonyms[types and their synonyms] for more. +|=== + [[cypher-deprecations-additions-removals-5.21]] == Neo4j 5.21 diff --git a/modules/ROOT/pages/values-and-types/property-structural-constructed.adoc b/modules/ROOT/pages/values-and-types/property-structural-constructed.adoc index 1f3841496..618ade925 100644 --- a/modules/ROOT/pages/values-and-types/property-structural-constructed.adoc +++ b/modules/ROOT/pages/values-and-types/property-structural-constructed.adoc @@ -89,8 +89,8 @@ However, not all types can be used in all places. | `FLOAT` | | `INTEGER` | `INT`, `SIGNED INTEGER` | `LIST` | `ARRAY`, `INNER_TYPE LIST`, `INNER_TYPE ARRAY` -| `LOCAL DATETIME` | `TIMESTAMP WITHOUT TIMEZONE` -| `LOCAL TIME` | `TIME WITHOUT TIMEZONE` +| `LOCAL DATETIME` | `TIMESTAMP WITHOUT TIME ZONE`, `TIMESTAMP WITHOUT TIMEZONE` +| `LOCAL TIME` | `TIME WITHOUT TIME ZONE`, `TIME WITHOUT TIMEZONE` | `MAP` | | `NODE` | `ANY NODE`, `VERTEX`, `ANY VERTEX` | `NOTHING` | @@ -100,8 +100,8 @@ However, not all types can be used in all places. | `PROPERTY VALUE` | `ANY PROPERTY VALUE` | `RELATIONSHIP` | `ANY RELATIONSHIP`, `EDGE`, `ANY EDGE` | `STRING` | `VARCHAR` -| `ZONED DATETIME` | `TIMESTAMP WITH TIMEZONE` -| `ZONED TIME` | `TIME WITH TIMEZONE` +| `ZONED DATETIME` | `TIMESTAMP WITH TIME ZONE`, `TIMESTAMP WITH TIMEZONE` +| `ZONED TIME` | `TIME WITH TIME ZONE`, `TIME WITH TIMEZONE` | `INNER_TYPE_1 \| INNER_TYPE_2...` | `ANY` |=== From 1044a9da74fb91f9a9a2ce5498f622b9b5da287c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Mon, 5 Aug 2024 15:58:30 +0200 Subject: [PATCH 04/20] Fix result format of relationships function (#1011) --- modules/ROOT/pages/functions/list.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/functions/list.adoc b/modules/ROOT/pages/functions/list.adoc index c7ae65b69..b118c9d60 100644 --- a/modules/ROOT/pages/functions/list.adoc +++ b/modules/ROOT/pages/functions/list.adoc @@ -424,8 +424,8 @@ A `LIST` containing all the `RELATIONSHIP` values in the `PATH` `p [role="queryresult",options="header,footer",cols="1* Date: Thu, 8 Aug 2024 14:17:36 +0200 Subject: [PATCH 05/20] Document Variable Scope Clause (#990) --- modules/ROOT/images/call_subquery_graph.svg | 10 +- .../pages/appendix/gql-conformance/index.adoc | 4 +- .../gql-conformance/supported-mandatory.adoc | 2 +- .../gql-conformance/supported-optional.adoc | 8 + modules/ROOT/pages/clauses/load-csv.adoc | 7 +- ...ions-additions-removals-compatibility.adoc | 48 ++ modules/ROOT/pages/genai-integrations.adoc | 7 +- .../ROOT/pages/patterns/shortest-paths.adoc | 7 +- .../operators/operators-detail.adoc | 28 +- .../ROOT/pages/subqueries/call-subquery.adoc | 655 +++++++++++++----- .../subqueries-in-transactions.adoc | 123 +--- 11 files changed, 623 insertions(+), 276 deletions(-) diff --git a/modules/ROOT/images/call_subquery_graph.svg b/modules/ROOT/images/call_subquery_graph.svg index 10e7f2ae6..932cf79da 100644 --- a/modules/ROOT/images/call_subquery_graph.svg +++ b/modules/ROOT/images/call_subquery_graph.svg @@ -1,9 +1,9 @@ - - + + - - + + - + diff --git a/modules/ROOT/pages/appendix/gql-conformance/index.adoc b/modules/ROOT/pages/appendix/gql-conformance/index.adoc index 2bc52908d..9448c41c4 100644 --- a/modules/ROOT/pages/appendix/gql-conformance/index.adoc +++ b/modules/ROOT/pages/appendix/gql-conformance/index.adoc @@ -1,8 +1,8 @@ :description: Overview of Cypher's conformance to GQL. = GQL conformance -*Last updated*: 5 July 2024 + -*Neo4j version*: 5.21 +*Last updated*: 8 August 2024 + +*Neo4j version*: 5.23 GQL is the new link:https://www.iso.org/home.html[ISO] International Standard query language for graph databases. diff --git a/modules/ROOT/pages/appendix/gql-conformance/supported-mandatory.adoc b/modules/ROOT/pages/appendix/gql-conformance/supported-mandatory.adoc index 42cd41056..4d4ee103d 100644 --- a/modules/ROOT/pages/appendix/gql-conformance/supported-mandatory.adoc +++ b/modules/ROOT/pages/appendix/gql-conformance/supported-mandatory.adoc @@ -81,7 +81,7 @@ This is not available in Cypher. | | xref:subqueries/call-subquery.adoc[`CALL` subqueries]. | GQL either imports variables implicitly, or explicitly using a variable scope clause. -In Cypher, `CALL` subqueries require an explicit importing `WITH` clause. +In Cypher, it is currently not possible to implicitly import variables. | 15.3 | diff --git a/modules/ROOT/pages/appendix/gql-conformance/supported-optional.adoc b/modules/ROOT/pages/appendix/gql-conformance/supported-optional.adoc index 47ba67e7f..c8c76ab6c 100644 --- a/modules/ROOT/pages/appendix/gql-conformance/supported-optional.adoc +++ b/modules/ROOT/pages/appendix/gql-conformance/supported-optional.adoc @@ -129,6 +129,14 @@ In Cypher, `trim()` removes any whitespace character. | | +| GP01 +| xref:subqueries/call-subquery.adoc[Inline procedure] +| + +| GP03 +| xref:subqueries/call-subquery.adoc#variable-scope-clause[Inline procedure with explicit nested variable scope] +| + | GQ01 | `USE` graph clause | xref:clauses/use.adoc[`USE`] diff --git a/modules/ROOT/pages/clauses/load-csv.adoc b/modules/ROOT/pages/clauses/load-csv.adoc index ea1998c5e..a67c11b2a 100644 --- a/modules/ROOT/pages/clauses/load-csv.adoc +++ b/modules/ROOT/pages/clauses/load-csv.adoc @@ -599,12 +599,15 @@ person_tmdbId,bio,born,bornIn,died,person_imdbId,name,person_poster,person_url ... ---- +[NOTE] +The below query uses a xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause] (introduced in Neo4j 5.23) to import variables into the `CALL` subquery. +If you are using an older version of Neo4j, use an xref:subqueries/call-subquery.adoc#importing-with[importing `WITH` clause] instead. + .Query [source, cypher] ---- LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/persons.csv' AS row -CALL { - WITH row +CALL (row) { MERGE (p:Person {tmdbId: row.person_tmdbId}) SET p.name = row.name, p.born = row.born } IN TRANSACTIONS OF 200 ROWS diff --git a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc index 62109c01f..83437bedb 100644 --- a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc +++ b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc @@ -19,8 +19,33 @@ Replacement syntax for deprecated and removed features are also indicated. [[cypher-deprecations-additions-removals-5.23]] == Neo4j 5.23 +=== Deprecated features + +[cols="2", options="header"] +|=== +| Feature +| Details + +a| +label:functionality[] +label:deprecated[] +[source, cypher, role="noheader"] +---- +UNWIND [0, 1, 2] AS x +CALL { + WITH x + RETURN x * 10 AS y +} +RETURN x, y +---- + +| Using the xref:subqueries/call-subquery.adoc#importing-with[`WITH` clause to import variables] to `CALL` subqueries is deprecated, and replaced with a xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause]. +It is also deprecated to use naked subqueries without a variable scope clause. +|=== + === Updated features + [cols="2", options="header"] |=== | Feature @@ -39,6 +64,29 @@ Introduced new GQL conformant aliases to duration types: `TIMESTAMP WITHOUT TIME See xref::values-and-types/property-structural-constructed.adoc#types-synonyms[types and their synonyms] for more. |=== +=== New features + +[cols="2", options="header"] +|=== +| Feature +| Details + +a| +label:functionality[] +label:new[] +[source, cypher, role="noheader"] +---- +UNWIND [0, 1, 2] AS x +CALL (x) { + RETURN x * 10 AS y +} +RETURN x, y +---- + +| Introduced a new xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause] to import variables in `CALL` subqueries. + +|=== + [[cypher-deprecations-additions-removals-5.21]] == Neo4j 5.21 diff --git a/modules/ROOT/pages/genai-integrations.adoc b/modules/ROOT/pages/genai-integrations.adoc index eba7d181b..0ffed1b6d 100644 --- a/modules/ROOT/pages/genai-integrations.adoc +++ b/modules/ROOT/pages/genai-integrations.adoc @@ -180,9 +180,8 @@ WITH collect(m) AS moviesList // <1> count(*) AS total, 100 AS batchSize // <2> UNWIND range(0, total, batchSize) AS batchStart // <3> -CALL { // <4> - WITH moviesList, batchStart, batchSize - WITH moviesList, batchStart, [movie IN moviesList[batchStart .. batchStart + batchSize] | movie.title || ': ' || movie.plot] AS resources // <5> +CALL (moviesList, batchStart, batchSize) { // <4> + WITH [movie IN moviesList[batchStart .. batchStart + batchSize] | movie.title || ': ' || movie.plot] AS resources // <5> CALL genai.vector.encodeBatch(batch, 'OpenAI', { token: $token }) YIELD index, vector CALL db.create.setNodeVectorProperty(moviesList[batchStart + index], 'embedding', vector) // <6> } IN TRANSACTIONS OF 1 ROW <7> @@ -194,6 +193,8 @@ Because vector embeddings can be very large, a larger batch size may require sig Too large a batch size may also exceed the provider's threshold. <3> Process `Movie` nodes in increments of `batchSize`. <4> A xref:subqueries/subqueries-in-transactions.adoc[`CALL` subquery] executes a separate transaction for each batch. +Note that this `CALL` subquery uses a xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause] (introduced in Neo4j 5.23) to import variables. +If you are using an older version of Neo4j, use an xref:subqueries/call-subquery.adoc#importing-with[importing `WITH` clause] instead. <5> `resources` is a list of strings, each being the concatenation of `title` and `plot` of one movie. <6> The procedure sets `vector` as value for the property named `embedding` for the node at position `batchStart + index` in the `moviesList`. <7> Set to `1` the amount of batches to be processed at once. diff --git a/modules/ROOT/pages/patterns/shortest-paths.adoc b/modules/ROOT/pages/patterns/shortest-paths.adoc index 2e9779c75..01e61f3ba 100644 --- a/modules/ROOT/pages/patterns/shortest-paths.adoc +++ b/modules/ROOT/pages/patterns/shortest-paths.adoc @@ -552,6 +552,10 @@ To have the planner choose the `StatefulShortestPath(Into)` instead, rewrite the For example, in the below query, using a `CALL` subquery ensures that the planner binds `a` and `b` to exactly one `Station` node respectively for each executed row, and this forces it to use `StatefulShortestPath(Into)` for each invocation of the `CALL` subquery, since a precondition of using this operator is that both boundary nodes match exactly one node each. +[NOTE] +The below query uses a xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause] (introduced in Neo4j 5.23) to import variables into the `CALL` subquery. +If you are using an older version of Neo4j, use an xref:subqueries/call-subquery.adoc#importing-with[importing `WITH` clause] instead. + .Query rewritten to use `StatefulShortestPath(Into)` [source,cypher] ---- @@ -559,8 +563,7 @@ PROFILE MATCH (a:Station {name: "Worcestershire Parkway"}), (b:Station) -CALL { - WITH a, b +CALL (a, b) { MATCH p = SHORTEST 1 (a)(()-[]-()-[]-()){1,}(b) RETURN p diff --git a/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc b/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc index 38759c6f5..d6c0f97d8 100644 --- a/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc +++ b/modules/ROOT/pages/planning-and-tuning/operators/operators-detail.adoc @@ -2811,13 +2811,16 @@ Total database accesses: 166, total allocated memory: 976 .TransactionApply ====== +[NOTE] +The below query uses a xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause] (introduced in Neo4j 5.23) to import variables into the `CALL` subquery. +If you are using an older version of Neo4j, use an xref:subqueries/call-subquery.adoc#importing-with[importing `WITH` clause] instead. + .Query [source, cypher] ---- PROFILE LOAD CSV FROM 'https://neo4j.com/docs/cypher-refcard/3.3/csv/artists.csv' AS line -CALL { - WITH line +CALL (line) { CREATE (a: Artist {name: line[0]}) RETURN a } IN TRANSACTIONS OF 100 ROWS @@ -3512,13 +3515,16 @@ This restricts the xref:planning-and-tuning/runtimes/index.adoc[Cypher runtime] .ArgumentTracker ====== +[NOTE] +The below query uses a xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause] (introduced in Neo4j 5.23) to import variables into the `CALL` subquery. +If you are using an older version of Neo4j, use an xref:subqueries/call-subquery.adoc#importing-with[importing `WITH` clause] instead. + .Query [source, cypher] ---- PROFILE MATCH (s:Person {name: 'me'}) -CALL { - WITH s +CALL (s) { SET s.seen = coalesce(s.seen + 1,1) RETURN s.seen AS result } @@ -4787,13 +4793,16 @@ Total database accesses: 9, total allocated memory: 64 .TransactionForeach ====== +[NOTE] +The below query uses a xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause] (introduced in Neo4j 5.23) to import variables into the `CALL` subquery. +If you are using an older version of Neo4j, use an xref:subqueries/call-subquery.adoc#importing-with[importing `WITH` clause] instead. + .Query [source, cypher] ---- PROFILE LOAD CSV FROM 'https://neo4j.com/docs/cypher-refcard/3.3/csv/artists.csv' AS line -CALL { - WITH line +CALL (line) { CREATE (a: Artist {name: line[0]}) } IN TRANSACTIONS OF 100 ROWS ---- @@ -4839,13 +4848,16 @@ Batch size 128 .SubqueryForeach ====== +[NOTE] +The below query uses a xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause] (introduced in Neo4j 5.23) to import variables into the `CALL` subquery. +If you are using an older version of Neo4j, use an xref:subqueries/call-subquery.adoc#importing-with[importing `WITH` clause] instead. + .Query [source, cypher] ---- PROFILE LOAD CSV FROM 'https://neo4j.com/docs/cypher-refcard/3.3/csv/artists.csv' AS line -CALL { - WITH line +CALL (line) { CREATE (a: Artist {name: line[0]}) } ---- diff --git a/modules/ROOT/pages/subqueries/call-subquery.adoc b/modules/ROOT/pages/subqueries/call-subquery.adoc index 636d47eea..84624ee19 100644 --- a/modules/ROOT/pages/subqueries/call-subquery.adoc +++ b/modules/ROOT/pages/subqueries/call-subquery.adoc @@ -1,19 +1,17 @@ = CALL subqueries -:description: This page describes how to use the CALL subquery with Cypher. +:description: This page describes how to use Cypher's `CALL` subquery. -The `CALL` clause can be used to invoke a subquery. -Unlike other subqueries in Cypher, it can be used to perform changes to the database (e.g. xref:clauses/create.adoc[] new nodes), and it requires an importing xref:clauses/with.adoc[] clause. +The `CALL` clause can be used to invoke subqueries that execute operations within a defined scope, thereby optimizing data handling and query efficiency. +Unlike other subqueries in Cypher, `CALL` subqueries can be used to perform changes to the database (e.g. xref:clauses/create.adoc[] new nodes). [NOTE] -==== The `CALL` clause is also used for calling procedures. -For descriptions of the `CALL` clause in this context, refer to xref::clauses/call.adoc[`CALL` procedure]. -==== +For descriptions of the `CALL` clause in this context, refer to the xref::clauses/call.adoc[`CALL` procedure]. [[call-example-graph]] == Example graph -The following graph is used for the examples below: +A graph with the following schema is used for the examples below: image::call_subquery_graph.svg[] @@ -21,33 +19,45 @@ To recreate the graph, run the following query in an empty Neo4j database: [source, cypher, role=test-setup] ---- -CREATE - (a:Person:Child {name: 'Alice', age: 20}), - (b:Person {name: 'Bob', age: 27}), - (c:Person:Parent {name: 'Charlie', age: 65}), - (d:Person {name: 'Dora', age: 30}) - CREATE (a)-[:FRIEND_OF]->(b) - CREATE (a)-[:CHILD_OF]->(c) - CREATE (a)-[:OWES {dollars: 20}]->(c) - CREATE (a)-[:OWES {dollars: 25}]->(b) - CREATE (b)-[:OWES {dollars: 35}]->(d) - CREATE (d)-[:OWES {dollars: 15}]->(b) - CREATE (d)-[:OWES {dollars: 30}]->(b) -CREATE (:Counter {count: 0}) +CREATE (teamA:Team {name: 'Team A'}), + (teamB:Team {name: 'Team B'}), + (teamC:Team {name: 'Team C'}), + (playerA:Player {name: 'Player A', age: 21}), + (playerB:Player {name: 'Player B', age: 23}), + (playerC:Player {name: 'Player C', age: 19}), + (playerD:Player {name: 'Player D', age: 30}), + (playerE:Player {name: 'Player E', age: 25}), + (playerF:Player {name: 'Player F', age: 35}), + (playerA)-[:PLAYS_FOR]->(teamA), + (playerB)-[:PLAYS_FOR]->(teamA), + (playerC)-[:PLAYS_FOR]->(teamA), + (playerD)-[:PLAYS_FOR]->(teamB), + (playerE)-[:PLAYS_FOR]->(teamC), + (playerF)-[:PLAYS_FOR]->(teamC), + (playerA)-[:FRIEND_OF]->(playerB), + (playerA)-[:FRIEND_OF]->(playerC), + (playerB)-[:FRIEND_OF]->(playerF), + (playerC)-[:FRIEND_OF]->(playerD), + (teamA)-[:OWES {dollars: 1500}]->(teamB), + (teamA)-[:OWES {dollars: 3000}]->(teamB), + (teamB)-[:OWES {dollars: 1700}]->(teamC), + (teamC)-[:OWES {dollars: 5000}]->(teamB) ---- -[[call-semantics]] -== Semantics +== Semantics and performance A `CALL` subquery is executed once for each incoming row. +The variables returned in a subquery are available to the outer scope of the enclosing query. -In the below example, the `CALL` subquery executes three times, one for each row that the `UNWIND` clause outputs. +.Basic example +==== +In this example, the `CALL` subquery executes three times, one for each row that the xref:clauses/unwind.adoc[`UNWIND`] clause outputs. .Query [source, cypher] ---- UNWIND [0, 1, 2] AS x -CALL { +CALL () { RETURN 'hello' AS innerReturn } RETURN innerReturn @@ -57,84 +67,360 @@ RETURN innerReturn [role="queryresult",options="header,footer",cols="m"] |=== | innerReturn + | 'hello' | 'hello' | 'hello' -d|Rows:3 + +d|Rows: 3 |=== +==== Each execution of a `CALL` subquery can observe changes from previous executions. +This allows for the accumulation of results and the progressive transformation of data within a single Cypher query. -.Query +.Incremental updates +==== +In this example, each iteration of the `CALL` subquery adds 1 to the `age` of `Player A` and the returned `newAge` reflects the `age` after each increment. + +.Incrementally update the age property of a Player [source, cypher] ---- -UNWIND [0, 1, 2] AS x -CALL { - MATCH (n:Counter) - SET n.count = n.count + 1 - RETURN n.count AS innerCount +UNWIND [1, 2, 3] AS x +CALL () { + MATCH (p:Player {name: 'Player A'}) + SET p.age = p.age + 1 + RETURN p.age AS newAge } -WITH innerCount -MATCH (n:Counter) -RETURN - innerCount, - n.count AS totalCount +WITH x, newAge +MATCH (p:Player {name: 'Player A'}) +RETURN x AS iteration, newAge, p.age AS totalAge ---- .Result -[role="queryresult",options="header,footer",cols=""2*(t) + RETURN collect(p) as players +} +RETURN t AS team, players +---- -[NOTE] +.Result +[source, role="queryresult",options="header,footer",cols="m,2m"] +|=== +| team +| players + +| (:Team {name: "Team A"}) +| [(:Player {name: "Player C", age: 19}), (:Player {name: "Player B", age: 23}), (:Player {name: "Player A", age: 24})] + +| (:Team {name: "Team B"}) +| [(:Player {name: "Player D", age: 30})] + +| (:Team {name: "Team C"}) +| [(:Player {name: "Player F", age: 35}), (:Player {name: "Player E", age: 25})] + +2+d|Rows: 3 +|=== + +The `CALL` subquery ensures that each `Team` is processed separately (one row per `Team` node), rather than having to hold every `Team` and `Player` node in heap memory simultaneously before collecting them into lists. +Using a `CALL` subquery can therefore reduce the amount of heap memory required for an operation. ==== -References to a variable in the outer scope that were not imported will introduce a new variable. + +[[import-variables]] +== Importing variables + +Variables from the outer scope must be explicitly imported into the inner scope of the `CALL` subquery, either by using a xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause] or an xref:subqueries/call-subquery.adoc#importing-with[importing `WITH` clause] (deprecated). +As the subquery is evaluated for each incoming input row, the imported variables are assigned the corresponding values from that row. + +[role=label--new-5.23] +[[variable-scope-clause]] +=== The variable scope clause + +Variables can be imported into a `CALL` subquery using a scope clause: `CALL ()`. +Using the scope clause disables the deprecated xref:subqueries/call-subquery.adoc#importing-with[importing `WITH`] clause. + +A scope clause can be used to import all, specific, or none of the variables from the outer scope. + +.Import specific variables from the outer scope ==== -As the subquery is evaluated for each incoming input row, the imported variables get bound to the corresponding values from the input row in each evaluation. +This example only imports the `p` variable from the outer scope and uses it to create a new, randomly generated, `rating` property for each `Player` node. +It then returns the `Player` node with the highest `rating`. -.Query +.Import one variable from the outer scope +[source, cypher, role=test-result-skip] +---- +MATCH (p:Player), (t:Team) +CALL (p) { + WITH rand() AS random + SET p.rating = random + RETURN p.name AS playerName, p.rating AS rating +} +RETURN playerName, rating, t AS team +ORDER BY rating +LIMIT 1 +---- + +.Result +[source, role="queryresult",options="header,footer",cols="3*m"] +|=== +| playerName +| rating +| team + +| "Player C" +| 0.9307432039870395 +| "Team A" + +3+d|Rows: 1 + +|=== + +To import additional variables, include them within the parentheses after `CALL`, separated by commas. +For example, to import both variables from the `MATCH` clause in the above query, modify the scope clause accordingly: `CALL (p, t)`. +==== + +.Import all variables +==== +To import all variables from the outer scope, use `CALL (*)`. +This example imports both the `p` and `t` variables and sets a new `lastUpdated` property on both. + +.Import all variables from the outer scope +[source, cypher, role=test-result-skip] +---- +MATCH (p:Player), (t:Team) +CALL (*) { + SET p.lastUpdated = timestamp() + SET t.lastUpdated = timestamp() +} +RETURN p.name AS playerName, + p.lastUpdated AS playerUpdated, + t.name AS teamName, + t.lastUpdated AS teamUpdated +LIMIT 1 +---- + +.Result +[source, role="queryresult",options="header,footer",cols="4*m"] +|=== + +| playerName +| playerUpdated +| teamName +| teamUpdated + +| "Player A" +| 1719304206653 +| "Team A" +| 1719304206653 + +4+d|Rows: 1 +|=== +==== + +.Import no variables +==== +To import no variables from the outer scope, use `CALL ()`. + +.Import no variables from the outer scope [source, cypher] ---- -UNWIND [0, 1, 2] AS x -CALL { - WITH x - RETURN x * 10 AS y +MATCH (t:Team) +CALL () { + MATCH (p:Player) + RETURN count(p) AS totalPlayers } -RETURN x, y +RETURN count(t) AS totalTeams, totalPlayers ---- .Result -[role="queryresult",options="header,footer",cols="2*(teams) + RETURN collect(p) as players +} +RETURN t AS teams, players +---- +* The scope clause’s variables cannot be re-declared in the subquery. + +.Not allowed +[source,cypher,role=test-fail] +---- +MATCH (t:Team) +CALL (t) { + WITH 'New team' AS t + MATCH (p:Player)-[:PLAYS_FOR]->(t) + RETURN collect(p) as players +} +RETURN t AS team, players +---- + +* The subquery cannot return a variable name which already exists in the outer scope. +To return imported variables they must be renamed. + +.Not allowed +[source,cypher,role=test-fail] +---- +MATCH (t:Team) +CALL (t) { + RETURN t +} +RETURN t +---- + +[role=label--deprecated] +[[importing-with]] +=== Importing `WITH` clause + +Variables can also be imported into a `CALL` subquery using an importing `WITH` clause. +Note that this syntax is not xref:appendix/gql-conformance/index.adoc[GQL conformant]. + +.Variables imported by `WITH` clause +[source, cypher] +---- +MATCH (t:Team) +CALL { + WITH t + MATCH (p:Player)-[:PLAYS_FOR]->(t) + RETURN collect(p) as players +} +RETURN t AS teams, players +---- + +.Click to read more about importing variables using the `WITH` clause +[%collapsible] +==== + +* Just as when using a variable scope clause, a subquery using an importing `WITH` clause cannot return a variable name which already exists in the outer scope. +To return imported variables they must be renamed. + +* The importing `WITH` clause must the first clause of a subquery (or the second clause, if directly following a `USE` clause). +* It is not possible to follow an importing `WITH` clause with any of the following clauses: `DISTINCT`, `ORDER BY`, `WHERE`, `SKIP`, and `LIMIT`. + +Attempting any of the above, will throw an error. +For example, the following query using a `WHERE` clause after an importing `WITH` clause will throw an error: + +.Not Allowed +[source, cypher, role=test-fail] +---- +UNWIND [[1,2],[1,2,3,4],[1,2,3,4,5]] AS l +CALL { + WITH l + WHERE size(l) > 2 + RETURN l AS largeLists +} +RETURN largeLists +---- + +.Error message +[source, error] +---- +Importing WITH should consist only of simple references to outside variables. +WHERE is not allowed. +---- + +A solution to this restriction, necessary for any filtering or ordering of an importing `WITH` clause, is to declare a second `WITH` clause after the importing `WITH` clause. +This second `WITH` clause will act as a regular `WITH` clause. +For example, the following query will not throw an error: + +.Allowed +[source, cypher] +---- +UNWIND [[1,2],[1,2,3,4],[1,2,3,4,5]] AS l +CALL { + WITH l + WITH l + WHERE size(l) > 2 + RETURN l AS largeLists +} +RETURN largeLists +---- + +.Result +[role="queryresult",options="header,footer",cols="1*(nextPerson) - RETURN current AS from, nextPerson AS to + SET nextPlayer:ListHead + CREATE(current)-[:IS_YOUNGER_THAN]->(nextPlayer) + RETURN current AS from, nextPlayer AS to } RETURN from.name AS name, @@ -171,81 +460,108 @@ RETURN ---- .Result -[role="queryresult",options="header,footer",cols="4*(other:Person) - RETURN o.dollars * -1 AS moneyOwed -UNION ALL - WITH p - OPTIONAL MATCH (other:Person)-[o:OWES]->(p) - RETURN o.dollars AS moneyOwed +MATCH (t:Team) +CALL (t) { + OPTIONAL MATCH (t)-[o:OWES]->(other:Team) + RETURN o.dollars * -1 AS moneyOwed + UNION ALL + OPTIONAL MATCH (other)-[o:OWES]->(t) + RETURN o.dollars AS moneyOwed } -RETURN p.name, sum(moneyOwed) AS amountOwing +RETURN t.name AS team, sum(moneyOwed) AS amountOwed +ORDER BY amountOwed DESC ---- .Result [role="queryresult",options="header,footer",cols="2*(p2:Player) + RETURN p2.name AS friend } -RETURN p.name, friend +RETURN p.name AS player, friend ---- .Result [role="queryresult",options="header,footer",cols="2*(c) - RETURN sum(o.dollars) AS owedAmount, c.name AS owedName +MATCH (t:Team) +CALL (t) { + MATCH (t)-[o:OWES]->(t2:Team) + RETURN sum(o.dollars) AS owedAmount, t2.name AS owedTeam } -RETURN p.name, owedAmount, owedName +RETURN t.name AS owingTeam, owedAmount, owedTeam ---- .Result [role="queryresult",options="header,footer",cols="3* 100 -CALL { - WITH n +CALL (n) { DETACH DELETE n } IN TRANSACTIONS ---- @@ -158,8 +158,7 @@ This example loads a CSV file with one transaction for every `2` input rows: [source, cypher] ---- LOAD CSV FROM 'file:///friends.csv' AS line -CALL { - WITH line +CALL (line) { CREATE (:Person {name: line[1], age: toInteger(line[2])}) } IN TRANSACTIONS OF 2 ROWS ---- @@ -191,8 +190,7 @@ For example: [source, cypher] ---- MATCH (n) -CALL { - WITH n +CALL (n) { DETACH DELETE n } IN TRANSACTIONS OF 2 ROWS ---- @@ -243,9 +241,8 @@ The following examples show how you can use `CALL { ... } IN TRANSACTIONS` on a ---- UNWIND graph.names() AS graphName LOAD CSV FROM 'file:///friends.csv' AS line -CALL { +CALL (*) { USE graph.byName( graphName ) - WITH line CREATE (:Person {name: line[1], age: toInteger(line[2])}) } IN TRANSACTIONS ---- @@ -306,7 +303,7 @@ While the declared batch size is 3, only the first 2 rows act on `composite.remo WITH ['composite.remoteGraph1', 'composite.remoteGraph2'] AS graphs UNWIND [0, 0, 1, 1, 1, 1, 0, 0] AS i WITH graphs[i] AS g -CALL { +CALL (g) { USE graph.byName( g ) CREATE () } IN TRANSACTIONS OF 3 ROWS @@ -339,8 +336,7 @@ due to division by zero. [source, cypher, role=test-fail] ---- UNWIND [4, 2, 1, 0] AS i -CALL { - WITH i +CALL (i) { CREATE (:Person {num: 100/i}) } IN TRANSACTIONS OF 2 ROWS RETURN i @@ -376,8 +372,7 @@ In the following example, `ON ERROR CONTINUE` is used after a failed inner trans [source, cypher] ---- UNWIND [1, 0, 2, 4] AS i -CALL { - WITH i +CALL (i) { CREATE (n:Person {num: 100/i}) // Note, fails when i = 0 RETURN n } IN TRANSACTIONS @@ -403,8 +398,7 @@ Note the difference in results when batching in transactions of 2 rows: [source, cypher, indent=0] ---- UNWIND [1, 0, 2, 4] AS i -CALL { - WITH i +CALL (i) { CREATE (n:Person {num: 100/i}) // Note, fails when i = 0 RETURN n } IN TRANSACTIONS @@ -435,8 +429,7 @@ In the following example, `ON ERROR BREAK` is used after a failed inner transact [source, cypher, indent=0] ---- UNWIND [1, 0, 2, 4] AS i -CALL { - WITH i +CALL (i) { CREATE (n:Person {num: 100/i}) // Note, fails when i = 0 RETURN n } IN TRANSACTIONS @@ -462,8 +455,7 @@ Note the difference in results when batching in transactions of 2 rows: [source, cypher, indent=0] ---- UNWIND [1, 0, 2, 4] AS i -CALL { - WITH i +CALL (i) { CREATE (n:Person {num: 100/i}) // Note, fails when i = 0 RETURN n } IN TRANSACTIONS @@ -489,8 +481,7 @@ In the following example, `ON ERROR FAIL` is used after the failed inner transac [source, cypher, indent=0, role=test-fail] ---- UNWIND [1, 0, 2, 4] AS i -CALL { - WITH i +CALL (i) { CREATE (n:Person {num: 100/i}) // Note, fails when i = 0 RETURN n } IN TRANSACTIONS @@ -529,8 +520,7 @@ Example of reporting status with `ON ERROR CONTINUE`: [source, cypher, indent=0, role=test-result-skip] ---- UNWIND [1, 0, 2, 4] AS i -CALL { - WITH i +CALL (i) { CREATE (n:Person {num: 100/i}) // Note, fails when i = 0 RETURN n } IN TRANSACTIONS @@ -557,8 +547,7 @@ Example of reporting status with `ON ERROR BREAK`: [source, cypher, indent=0] ---- UNWIND [1, 0, 2, 4] AS i -CALL { - WITH i +CALL (i) { CREATE (n:Person {num: 100/i}) // Note, fails when i = 0 RETURN n } IN TRANSACTIONS @@ -585,8 +574,7 @@ Reporting status with `ON ERROR FAIL` is disallowed: [source, cypher, role=test-fail] ---- UNWIND [1, 0, 2, 4] AS i -CALL { - WITH i +CALL (i) { CREATE (n:Person {num: 100/i}) // Note, fails when i = 0 RETURN n } IN TRANSACTIONS @@ -625,8 +613,7 @@ This example creates `Person` nodes from a unique `tmdbId` value assigned to eac [source, cypher] ---- LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/persons.csv' AS row -CALL { - WITH row +CALL (row) { CREATE (p:Person {tmdbId: row.person_tmdbId}) SET p.name = row.name, p.born = row.born } IN 3 CONCURRENT TRANSACTIONS OF 10 ROWS @@ -684,8 +671,7 @@ Note that there are only three different years in the CSV file, meaning hat only [source, cypher, role=test-fail] ---- LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/movies.csv' AS row -CALL { - WITH row +CALL (row) { MERGE (m:Movie {movieId: row.movieId}) MERGE (y:Year {year: row.year}) MERGE (m)-[r:RELEASED_IN]->(y) @@ -709,8 +695,7 @@ It returns the `transactionID`, `commitStatus` and `errorMessage` of the failed [source, cypher] ---- LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/movies.csv' AS row -CALL { - WITH row +CALL (row) { MERGE (m:Movie {movieId: row.movieId}) MERGE (y:Year {year: row.year}) MERGE (m)-[r:RELEASED_IN]->(y) @@ -724,7 +709,7 @@ RETURN status.transactionId AS transaction, status.committed AS commitStatus, st [source, "queryresult"] ---- +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| transaction | commitStatus | errorMessage | +| transaction | commitStatus | errorMessage | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | "neo4j-transaction-169" | FALSE | "ForsetiClient[transactionId=169, clientId=11] can't acquire ExclusiveLock{owner=ForsetiClient[transactionId=168, clientId=9]} on NODE_RELATIONSHIP_GROUP_DELETE(46) because holders of that lock are waiting for ForsetiClient[transactionId=169, clientId=11]. | | | \ Wait list:ExclusiveLock[ | @@ -768,16 +753,14 @@ While failed transactions may be more efficiently retried using a link:{neo4j-do [source, cypher] ---- LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/movies.csv' AS row -CALL { - WITH row +CALL (row) { MERGE (m:Movie {movieId: row.movieId}) MERGE (y:Year {year: row.year}) MERGE (m)-[r:RELEASED_IN]->(y) } IN 2 CONCURRENT TRANSACTIONS OF 10 ROWS ON ERROR CONTINUE REPORT STATUS as status WITH * WHERE status.committed = false -CALL { - WITH row +CALL (row) { MERGE (m:Movie {movieId: row.movieId}) MERGE (y:Year {year: row.year}) MERGE (m)-[r:RELEASED_IN]->(y) @@ -795,59 +778,3 @@ These are the restrictions on queries that use `CALL { ... } IN TRANSACTIONS`: * A `CALL { ... } IN TRANSACTIONS` in a `UNION` is not supported. * A `CALL { ... } IN TRANSACTIONS` after a write clause is not supported, unless that write clause is inside a `CALL { ... } IN TRANSACTIONS`. -Additionally, there are some restrictions that apply when using an importing `WITH` clause in a `CALL` subquery: - -* Only variables imported with the importing `WITH` clause can be used. -* No expressions or aliasing are allowed within the importing `WITH` clause. -* It is not possible to follow an importing `WITH` clause with any of the following clauses: `DISTINCT`, `ORDER BY`, `WHERE`, `SKIP`, and `LIMIT`. - -Attempting any of the above, will throw an error. -For example, the following query using a `WHERE` clause after an importing `WITH` clause will throw an error: - -.Query -[source, cypher, role=test-fail] ----- -UNWIND [[1,2],[1,2,3,4],[1,2,3,4,5]] AS l -CALL { - WITH l - WHERE size(l) > 2 - RETURN l AS largeLists -} -RETURN largeLists ----- - -.Error message -[source, error] ----- -Importing WITH should consist only of simple references to outside variables. -WHERE is not allowed. ----- - -A solution to this restriction, necessary for any filtering or ordering of an importing `WITH` clause, is to declare a second `WITH` clause after the importing `WITH` clause. -This second `WITH` clause will act as a regular `WITH` clause. -For example, the following query will not throw an error: - -.Query -[source, cypher] ----- -UNWIND [[1,2],[1,2,3,4],[1,2,3,4,5]] AS l -CALL { - WITH l - WITH size(l) AS size, l AS l - WHERE size > 2 - RETURN l AS largeLists -} -RETURN largeLists ----- - -.Result -[role="queryresult",options="header,footer",cols="1* Date: Thu, 8 Aug 2024 16:21:22 +0200 Subject: [PATCH 06/20] Fix typos on parsing page (#1014) --- modules/ROOT/pages/syntax/parsing.adoc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/ROOT/pages/syntax/parsing.adoc b/modules/ROOT/pages/syntax/parsing.adoc index 0a64ed215..54db83bde 100644 --- a/modules/ROOT/pages/syntax/parsing.adoc +++ b/modules/ROOT/pages/syntax/parsing.adoc @@ -15,7 +15,7 @@ Additional documentation on escaping rules for `STRING` literals, names and regu * xref::queries/expressions.adoc#expressions-string-literals[String literal escape sequences] * xref::syntax/naming.adoc#symbolic-names-escaping-rules[Using special characters in names] -* xref::clauses/where.adoc#escaping-in-regular-expressions[Regular epxressions] +* xref::clauses/where.adoc#escaping-in-regular-expressions[Regular expressions] The following example escapes the unicode character `A` (`\u0041`) in the keyword `MATCH`: @@ -44,9 +44,9 @@ The following unicode characters are considered as whitespace: [options="header", cols="1,2"] |=== | Description | List of included Unicode characters -| Unicode general gategory Zp | `\u2029` -| Unicode general gategory Zs | `\u0020` (space), `\u1680`, `\u2000-200A`, `\u202F`, `\u205F`, `\u3000` -| Unicode general gategory class Zl | `\u2028` +| Unicode general category Zp | `\u2029` +| Unicode general category Zs | `\u0020` (space), `\u1680`, `\u2000-200A`, `\u202F`, `\u205F`, `\u3000` +| Unicode general category class Zl | `\u2028` | Horizontal tabulation | `\t`, `\u0009` | Line feed | `\n`, `\u000A` | Vertical tabulation | `\u000B` From 2014d2a04257253f6a398e809a2e2a7613dad205 Mon Sep 17 00:00:00 2001 From: Gem Lamont <106068376+gem-neo4j@users.noreply.github.com> Date: Fri, 9 Aug 2024 09:22:17 +0200 Subject: [PATCH 07/20] Add further considerations for CASE expressions (#1013) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jens Pryce-Åklundh <112686610+JPryce-Aklundh@users.noreply.github.com> --- modules/ROOT/pages/queries/case.adoc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/modules/ROOT/pages/queries/case.adoc b/modules/ROOT/pages/queries/case.adoc index 04ac4f195..1dae13b99 100644 --- a/modules/ROOT/pages/queries/case.adoc +++ b/modules/ROOT/pages/queries/case.adoc @@ -323,3 +323,29 @@ RETURN n.name, n.colorCode |=== For more information about using the `SET` clause, see xref::clauses/set.adoc[SET]. + +== Further considerations + +`CASE` result branches are statically checked prior to execution. +This means that if a branch is not semantically correct, it will still throw an exception, even if that branch may never be executed during runtime. + +In the following example, `date` is statically known to be a `STRING` value, and therefore would fail if treated as a `DATE` value. + +.Not allowed +[source, cypher, role=test-fail] +---- +WITH "2024-08-05" AS date, "string" AS type +RETURN CASE type + WHEN "string" THEN datetime(date) + WHEN "date" THEN datetime({year: date.year, month: date.month, day: date.day}) + ELSE datetime(date) +END AS dateTime +---- + +.Error message +[source, error] +---- +Type mismatch: expected Map, Node, Relationship, Point, Duration, Date, Time, LocalTime, LocalDateTime or DateTime but was String (line 4, column 38 (offset: 136)) +" WHEN 'date' THEN datetime({year: date.year, month: date.month, day: date.day})" + ^ +---- \ No newline at end of file From 20b83d771468bddc504690a94f880464d333968c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Fri, 9 Aug 2024 13:41:00 +0200 Subject: [PATCH 08/20] Remove link to Cartesian CRSs (#1016) --- modules/ROOT/pages/values-and-types/spatial.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/values-and-types/spatial.adoc b/modules/ROOT/pages/values-and-types/spatial.adoc index a7daf8684..dce319fb1 100644 --- a/modules/ROOT/pages/values-and-types/spatial.adoc +++ b/modules/ROOT/pages/values-and-types/spatial.adoc @@ -95,10 +95,10 @@ RETURN toInteger(point.distance(p1, p2)/1000) AS km Two Cartesian Coordinate Reference Systems (CRS) are supported, modeling points in euclidean space: -* link:https://spatialreference.org/ref/sr-org/7203/[Cartesian 2D] +* *Cartesian 2D* ** A 2D point in the _Cartesian_ CRS is specified with a map containing `x` and `y` coordinate values ** Specifying this CRS can be done using either the name 'cartesian' or the SRID 7203 as described in xref::functions/spatial.adoc#functions-point-cartesian-2d[point() - Cartesian 2D] -* link:https://spatialreference.org/ref/sr-org/9157/[Cartesian 3D] +* *Cartesian 3D* ** A 3D point in the _Cartesian_ CRS is specified with a map containing `x`, `y` and `z` coordinate values ** Specifying this CRS can be done using either the name 'cartesian-3d' or the SRID 9157 as described in xref::functions/spatial.adoc#functions-point-cartesian-3d[point() - Cartesian 3D)] From 21d63cc9641ecd8b361cdac32870ae5f0588e7a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Fri, 9 Aug 2024 13:53:55 +0200 Subject: [PATCH 09/20] Fix typo in Patterns reference (#1017) --- modules/ROOT/pages/patterns/reference.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/patterns/reference.adoc b/modules/ROOT/pages/patterns/reference.adoc index f145e88bb..d9da89346 100644 --- a/modules/ROOT/pages/patterns/reference.adoc +++ b/modules/ROOT/pages/patterns/reference.adoc @@ -779,7 +779,7 @@ Matches one or more relationships with type `R` and of any direction, and any no ()-[:R]-+() ---- -Matches paths consisting of two inbound subpaths, one with relationships of type `A` and one with relationships of type `B`, meeting at a node with label `A`: +Matches paths consisting of two inbound subpaths, one with relationships of type `R` and one with relationships of type `S`, meeting at a node with label `A`: [source, role=noheader] ---- ()-[:R]->+(:A)<-[:S]-+() From 79cbee9c0f908781464d530e681f687382ba740a Mon Sep 17 00:00:00 2001 From: Phil Wright <95368282+phil198@users.noreply.github.com> Date: Mon, 12 Aug 2024 09:27:06 +0100 Subject: [PATCH 10/20] adding health warning about insecure protocols for LOAD CSV (#1006) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit adds a warning against allowing insecure protocols for `LOAD CSV` this PR is the docs counterpart to https://github.com/neo-technology/neo4j/pull/26403 I will add a duplicate warning to https://neo4j.com/docs/cypher-manual/current/clauses/load-csv/ https://neo4j.com/docs/operations-manual/5/authentication-authorization/load-privileges/ and possibly https://neo4j.com/docs/getting-started/data-import/csv-import/ once the wording of this one is finalised. --------- Co-authored-by: Jens Pryce-Åklundh <112686610+JPryce-Aklundh@users.noreply.github.com> --- modules/ROOT/pages/clauses/load-csv.adoc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/ROOT/pages/clauses/load-csv.adoc b/modules/ROOT/pages/clauses/load-csv.adoc index a67c11b2a..2880d2526 100644 --- a/modules/ROOT/pages/clauses/load-csv.adoc +++ b/modules/ROOT/pages/clauses/load-csv.adoc @@ -90,6 +90,15 @@ You can import data from a CSV file hosted on a remote path. `LOAD CSV` supports accessing CSV files via HTTPS, HTTP, and FTP (with or without credentials). It also follows redirects, except those changing the protocol (for security reasons). +[IMPORTANT] +==== +It is strongly recommended to permit resource loading only over secure protocols such as HTTPS instead of insecure protocols like HTTP. +This can be done by limiting the link:{neo4j-docs-base-uri}/operations-manual/{page-version}/authentication-authorization/load-privileges/#access-control-load-cidr/[load privileges] to only trusted sources that use secure protocols. +If allowing an insecure protocol is absolutely unavoidable, Neo4j takes measures internally to enhance the security of these requests within their limitations. +However, this means that insecure URLs on virtual hosts will not function unless you add the JVM argument `-Dsun.net.http.allowRestrictedHeaders=true` to the configuration setting link:{neo4j-docs-base-uri}/operations-manual/{page-version}/configuration/configuration-settings/#config_server.jvm.additional/[jvm.additional]. +==== + + .Import artists name and year information from a remote file via HTTPS ==== From 750a641f579a011b8075f96657dc33604bd85c9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:38:02 +0200 Subject: [PATCH 11/20] fix GQL table and update on CALL (#1018) --- .../pages/appendix/gql-conformance/index.adoc | 2 +- .../gql-conformance/supported-mandatory.adoc | 17 ----------------- .../gql-conformance/supported-optional.adoc | 11 +++++++++-- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/modules/ROOT/pages/appendix/gql-conformance/index.adoc b/modules/ROOT/pages/appendix/gql-conformance/index.adoc index 9448c41c4..e5743548f 100644 --- a/modules/ROOT/pages/appendix/gql-conformance/index.adoc +++ b/modules/ROOT/pages/appendix/gql-conformance/index.adoc @@ -1,7 +1,7 @@ :description: Overview of Cypher's conformance to GQL. = GQL conformance -*Last updated*: 8 August 2024 + +*Last updated*: 9 August 2024 + *Neo4j version*: 5.23 GQL is the new link:https://www.iso.org/home.html[ISO] International Standard query language for graph databases. diff --git a/modules/ROOT/pages/appendix/gql-conformance/supported-mandatory.adoc b/modules/ROOT/pages/appendix/gql-conformance/supported-mandatory.adoc index 4d4ee103d..478988f85 100644 --- a/modules/ROOT/pages/appendix/gql-conformance/supported-mandatory.adoc +++ b/modules/ROOT/pages/appendix/gql-conformance/supported-mandatory.adoc @@ -71,23 +71,6 @@ The only way to guarantee row order in Neo4j is to use xref:clauses/order-by.ado | xref:clauses/return.adoc[`RETURN`] | -| 15.1 -| and -| xref:clauses/call.adoc[`CALL` procedures], xref:subqueries/call-subquery.adoc[`CALL` subqueries]. -| GQL defines an `OPTIONAL CALL` statement, enabling optional procedure and subquery calling. -This is not available in Cypher. - -| 15.2 -| -| xref:subqueries/call-subquery.adoc[`CALL` subqueries]. -| GQL either imports variables implicitly, or explicitly using a variable scope clause. -In Cypher, it is currently not possible to implicitly import variables. - -| 15.3 -| -| xref:clauses/call.adoc[`CALL` procedure] -| - | 16.2 | | xref:clauses/limit.adoc[`LIMIT`] diff --git a/modules/ROOT/pages/appendix/gql-conformance/supported-optional.adoc b/modules/ROOT/pages/appendix/gql-conformance/supported-optional.adoc index c8c76ab6c..b71364b84 100644 --- a/modules/ROOT/pages/appendix/gql-conformance/supported-optional.adoc +++ b/modules/ROOT/pages/appendix/gql-conformance/supported-optional.adoc @@ -130,11 +130,18 @@ In Cypher, `trim()` removes any whitespace character. | | GP01 -| xref:subqueries/call-subquery.adoc[Inline procedure] +| Inline procedure +| xref:subqueries/call-subquery.adoc[`CALL` subqueries] | | GP03 -| xref:subqueries/call-subquery.adoc#variable-scope-clause[Inline procedure with explicit nested variable scope] +| Inline procedure with explicit nested variable scope +| xref:subqueries/call-subquery.adoc#variable-scope-clause[`CALL` subqueries -> Variable scope clause] +| + +| GP04 +| Named procedure calls +| xref:clauses/call.adoc[`CALL` procedure] | | GQ01 From e6d0a2768e24a15e84e49f031ee902679b2c7f25 Mon Sep 17 00:00:00 2001 From: Phil Wright <95368282+phil198@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:18:57 +0100 Subject: [PATCH 12/20] link description correction (#1020) correcting link text to match https://github.com/neo4j/docs-getting-started/pull/410#discussion_r1713782822 --- modules/ROOT/pages/clauses/load-csv.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/clauses/load-csv.adoc b/modules/ROOT/pages/clauses/load-csv.adoc index 2880d2526..fd19b94e7 100644 --- a/modules/ROOT/pages/clauses/load-csv.adoc +++ b/modules/ROOT/pages/clauses/load-csv.adoc @@ -95,7 +95,7 @@ It also follows redirects, except those changing the protocol (for security reas It is strongly recommended to permit resource loading only over secure protocols such as HTTPS instead of insecure protocols like HTTP. This can be done by limiting the link:{neo4j-docs-base-uri}/operations-manual/{page-version}/authentication-authorization/load-privileges/#access-control-load-cidr/[load privileges] to only trusted sources that use secure protocols. If allowing an insecure protocol is absolutely unavoidable, Neo4j takes measures internally to enhance the security of these requests within their limitations. -However, this means that insecure URLs on virtual hosts will not function unless you add the JVM argument `-Dsun.net.http.allowRestrictedHeaders=true` to the configuration setting link:{neo4j-docs-base-uri}/operations-manual/{page-version}/configuration/configuration-settings/#config_server.jvm.additional/[jvm.additional]. +However, this means that insecure URLs on virtual hosts will not function unless you add the JVM argument `-Dsun.net.http.allowRestrictedHeaders=true` to the configuration setting link:{neo4j-docs-base-uri}/operations-manual/{page-version}/configuration/configuration-settings/#config_server.jvm.additional/[`server.jvm.additional`]. ==== From d4ec5de74a73603720bbbbbff427c61c9aef23b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Tue, 13 Aug 2024 13:25:39 +0200 Subject: [PATCH 13/20] Remove Enterprise Edition label from GenAI plugin page (#1019) --- modules/ROOT/pages/genai-integrations.adoc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/genai-integrations.adoc b/modules/ROOT/pages/genai-integrations.adoc index 0ffed1b6d..5168f0d01 100644 --- a/modules/ROOT/pages/genai-integrations.adoc +++ b/modules/ROOT/pages/genai-integrations.adoc @@ -1,11 +1,12 @@ :description: Information about Neo4j's GenAI integrations. -:page-role: enterprise-edition new-5.17 +:page-role: new-5.17 :test-setup-dump: https://github.com/neo4j-graph-examples/recommendations/raw/main/data/recommendations-50.dump include::https://raw.githubusercontent.com/neo4j-graphacademy/courses/main/asciidoc/courses/llm-fundamentals/ad.adoc[] [[genai-integrations]] = GenAI integrations + Neo4j's xref:indexes/semantic-indexes/vector-indexes.adoc[] and xref:functions/vector.adoc[] allow you to calculate the similarity between node and relationship properties in a graph. A prerequisite for using these features is that vector embeddings have been set as properties of these entities. The GenAI plugin enables the creation of such embeddings using GenAI providers. @@ -20,10 +21,13 @@ For a hands-on guide on how to use the GenAI plugin, see link:https://neo4j.com/ The GenAI plugin is enabled by default in Neo4j Aura. -For self-managed instances, the plugin is only available on Enterprise Edition and needs to be installed. +The plugin needs to be installed on self-managed instances. This is done by moving the `neo4j-genai.jar` file from `/products` to `/plugins` in the Neo4j home directory, or, if you are using Docker, by starting the Docker container with the extra parameter `--env NEO4J_PLUGINS='["genai"]'`. For more information, see link:{neo4j-docs-base-uri}/operations-manual/{page-version}/configuration/plugins/[Operations Manual -> Configure plugins]. +[NOTE] +Prior to Neo4j 5.23, the GenAI plugin was only available on Neo4j Enterprise Edition. + [[example-graph]] == Example graph From 63475f5833e32a0fb3e2ec59147481ddd98b2483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Tue, 13 Aug 2024 14:20:23 +0200 Subject: [PATCH 14/20] Update GQL wording (#1021) --- modules/ROOT/pages/appendix/gql-conformance/index.adoc | 4 ++-- .../pages/appendix/gql-conformance/unsupported-mandatory.adoc | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/ROOT/pages/appendix/gql-conformance/index.adoc b/modules/ROOT/pages/appendix/gql-conformance/index.adoc index e5743548f..5b58aafb1 100644 --- a/modules/ROOT/pages/appendix/gql-conformance/index.adoc +++ b/modules/ROOT/pages/appendix/gql-conformance/index.adoc @@ -20,8 +20,8 @@ RETURN m.title ---- Cypher supports the majority of mandatory GQL features. -For a full list, see xref:appendix/gql-conformance/supported-mandatory.adoc[]. -There are, however, currently a few mandatory GQL features not implemented in Cypher. +For a full list see xref:appendix/gql-conformance/supported-mandatory.adoc[]. +There are, however, currently a few mandatory GQL features not yet in Cypher that Neo4j is actively working towards implementing. These are listed in the page xref:appendix/gql-conformance/unsupported-mandatory.adoc[]. Neo4j is also working towards increasing its support of optional GQL features. diff --git a/modules/ROOT/pages/appendix/gql-conformance/unsupported-mandatory.adoc b/modules/ROOT/pages/appendix/gql-conformance/unsupported-mandatory.adoc index 3ff2558b2..98c143dcb 100644 --- a/modules/ROOT/pages/appendix/gql-conformance/unsupported-mandatory.adoc +++ b/modules/ROOT/pages/appendix/gql-conformance/unsupported-mandatory.adoc @@ -1,7 +1,8 @@ :description: Information about mandatory GQL features not currently supported by Cypher. = Currently unsupported mandatory GQL features -Cypher supports most mandatory GQL features, though there are a few instances where its current functionality diverges. +Cypher supports most mandatory GQL features. +There are, however, currently a few mandatory GQL features not yet in Cypher that Neo4j is actively working towards implementing. The table below provides an overview of these GQL features and, where applicable, their functional equivalents in Neo4j. Unlike optional GQL features, mandatory GQL features are not assigned a GQL feature ID code. From e3ce55fdb4ad6d614dfe3d7c47030d066dc426c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Wed, 14 Aug 2024 14:18:43 +0200 Subject: [PATCH 15/20] Update remaining queries using shortestPath() (#1022) --- modules/ROOT/pages/queries/basic.adoc | 39 +++++++++++++++--------- modules/ROOT/pages/queries/concepts.adoc | 6 ++-- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/modules/ROOT/pages/queries/basic.adoc b/modules/ROOT/pages/queries/basic.adoc index 7a73dfa20..530e50616 100644 --- a/modules/ROOT/pages/queries/basic.adoc +++ b/modules/ROOT/pages/queries/basic.adoc @@ -795,32 +795,43 @@ LIMIT 5 |=== [NOTE] -==== The quantifier used in the above two examples was introduced with the release of xref::patterns/variable-length-patterns.adoc#quantified-path-patterns[quantified path patterns] in Neo4j 5.9. Before that, the only way in Cypher to match paths of a variable length was with a variable-length relationship. -This syntax is still available in Cypher. -Read more about it xref::patterns/reference.adoc#variable-length-relationships[here]. -==== +This syntax is still available in Cypher, but it is not xref:appendix/gql-conformance/index.adoc[GQL conformant]. +For more information, see xref::patterns/reference.adoc#variable-length-relationships[Patterns -> Syntax and semantics -> Variable length relationships]. -To find the shortest possible path between two nodes, use the `shortestPath` algorithm. -For example, this query matches the shorest path in the graph between the two nodes `Tom Hanks` and `Keanu Reeves`: +The xref:patterns/shortest-paths.adoc[`SHORTEST`] keyword can be used to find a variation of the shortest paths between two nodes. +In this example, `ALL SHORTEST` paths between the two nodes `Keanu Reeves` and `Tom Cruise` are found. +The xref:functions/aggregating.adoc#functions-count[`count()`] function calculates the number of these shortest paths while the xref:functions/scalar.adoc#functions-length[`length()`] function calculates the length of each path in terms of traversed relationships. .Query [source, cypher] ---- -MATCH p=shortestPath( -(:Person {name:"Keanu Reeves"})-[*]-(:Person {name:"Tom Hanks"}) -) -RETURN p +MATCH p = ALL SHORTEST (:Person {name:"Keanu Reeves"})--+(:Person {name:"Tom Cruise"}) +RETURN count(p) AS pathCount, length(p) AS pathLength ---- -This is the returned path: +The results show that 2 different paths are tied for the shortest length. -image::introduction_example2.svg[width="500",role="middle] +.Result +[role="queryresult",options="header,footer",cols="2* Syntax and semantics -> The `shortestPath()` and `allShortestPaths()` functions]. -More information can be found in the section on xref::patterns/index.adoc[Patterns]. +For more information about graph pattern matching, see xref::patterns/index.adoc[Patterns]. [[find-recommendations]] == Finding recommendations diff --git a/modules/ROOT/pages/queries/concepts.adoc b/modules/ROOT/pages/queries/concepts.adoc index cc7b37d47..f0caa0fd8 100644 --- a/modules/ROOT/pages/queries/concepts.adoc +++ b/modules/ROOT/pages/queries/concepts.adoc @@ -71,13 +71,13 @@ This example uses a xref:patterns/variable-length-patterns.adoc#quantified-relat The xref:syntax/operators.adoc#syntax-using-the-distinct-operator[DISTINCT] operator is used to ensure that the `RETURN` clause only returns unique nodes. Paths can also be assigned variables. -For example, the below query binds a whole path pattern, which matches the xref:patterns/reference.adoc#shortest-functions[shortest path] from `Anna` to another `Person` node in the graph up to `10` hops away with the `nationality` property set to `Canadian`. +For example, the below query binds a whole path pattern, which matches the xref:patterns/shortest-paths.adoc[`SHORTEST`] path from `Anna` to another `Person` node in the graph with a `nationality` property set to `Canadian`. In this case, the `RETURN` clause returns the full path between the two nodes. [source, cypher] ---- -MATCH p=shortestPath((:Person {name: 'Anna'})-[:KNOWS*1..10]-(:Person {nationality: 'Canadian'})) +MATCH p = SHORTEST 1 (:Person {name: 'Anna'})-[:KNOWS]-+(:Person {nationality: 'Canadian'}) RETURN p ---- -For more information about graph patterns, see the section on xref:patterns/index.adoc[]. +For more information about graph pattern matching, see xref:patterns/index.adoc[]. From 8df83edea6ea85cf3a2dca0ce05dbf17b66aab12 Mon Sep 17 00:00:00 2001 From: Matthew Parnell Date: Fri, 16 Aug 2024 10:37:58 +0100 Subject: [PATCH 16/20] Add new vector index settings (#1009) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have exposed quantization, and `M` and `efConstruction` hyperparameters for the vector index. We have also allowed the similarity function to be defaulted to `'cosine'`, and for the dimensions to not need to be specified. --------- Co-authored-by: Richard Sill <156673635+rsill-neo4j@users.noreply.github.com> Co-authored-by: Jens Pryce-Åklundh <112686610+JPryce-Aklundh@users.noreply.github.com> --- ...ions-additions-removals-compatibility.adoc | 25 ++++ .../semantic-indexes/vector-indexes.adoc | 107 +++++++++++++++--- modules/ROOT/pages/indexes/syntax.adoc | 11 +- 3 files changed, 123 insertions(+), 20 deletions(-) diff --git a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc index 83437bedb..e93567124 100644 --- a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc +++ b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc @@ -85,6 +85,31 @@ RETURN x, y | Introduced a new xref:subqueries/call-subquery.adoc#variable-scope-clause[variable scope clause] to import variables in `CALL` subqueries. +a| +label:functionality[] +label:new[] +[source, cypher, role=noheader] +---- +CREATE VECTOR INDEX moviePlots IF NOT EXISTS +FOR (m:Movie) +ON m.embedding +OPTIONS {indexConfig: { +`vector.quantization.enabled`: true +`vector.hnsw.m`: 16, +`vector.hnsw.ef_construction`: 100, +}} +---- + +a| Introduced the following xref:indexes/semantic-indexes/vector-indexes.adoc#configuration-settings[configuration settings] for vector indexes: + +* `vector.quantization.enabled`: allows for enabling quantization, which can accelerate search performance but can also slightly decrease accuracy. + +* `vector.hnsw.m`: controls the maximum number of connections each node has in the index's internal graph. + +* `vector.hnsw.ef_construction`: sets the number of nearest neighbors tracked during the insertion of vectors into the index's internal graph. + +Additionally, as of Neo4j 5.23, it is no longer mandatory to configure the settings `vector.dimensions` and `vector.similarity_function` when creating a vector index. + |=== [[cypher-deprecations-additions-removals-5.21]] diff --git a/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc b/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc index c8bedbc44..6029c675c 100644 --- a/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc +++ b/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc @@ -92,7 +92,7 @@ Creating indexes requires link:{neo4j-docs-base-uri}/operations-manual/{page-ver CREATE VECTOR INDEX moviePlots IF NOT EXISTS // <1> FOR (m:Movie) ON m.embedding -OPTIONS {indexConfig: { +OPTIONS { indexConfig: { `vector.dimensions`: 1536, `vector.similarity_function`: 'cosine' }} // <2> @@ -103,8 +103,10 @@ This means that its default behavior is to throw an error if an attempt is made With `IF NOT EXISTS`, no error is thrown and nothing happens should an index with the same name, schema or both already exist. It may still throw an error should a constraint with the same name exist. As of Neo4j 5.17, an informational notification is returned when nothing happens, showing the existing index which blocks the creation. -<2> The `OPTIONS` map is mandatory since a vector index cannot be created without setting the vector dimensions and similarity function. -In this example, the vector dimension is set to `1536` and the vector similarity function is `cosine`, which is generally the preferred similarity function for text embeddings. +<2> Prior to Neo4j 5.23, the `OPTIONS` map was mandatory since a vector index could not be created without setting the vector dimensions and similarity function. +Since Neo4j 5.23, both can be omitted. +To read more about the available configuration settings, see xref:indexes/semantic-indexes/vector-indexes.adoc#configuration-settings[]. +In this example, the vector dimension is explicitly set to `1536` and the vector similarity function to `'cosine'`, which is generally the preferred similarity function for text embeddings. To read more about the available similarity functions, see xref:indexes/semantic-indexes/vector-indexes.adoc#similarity-functions[]. [NOTE] @@ -117,12 +119,78 @@ You can also create a vector index for relationships with a particular type on a ---- CREATE VECTOR INDEX name IF NOT EXISTS FOR ()-[r:REL_TYPE]-() ON (r.embedding) -OPTIONS {indexConfig: { +OPTIONS { indexConfig: { `vector.dimensions`: $dimension, `vector.similarity_function`: $similarityFunction }} ---- +[[configuration-settings]] +=== Configuration settings + +For more information about the values accepted by different index providers, see xref:indexes/semantic-indexes/vector-indexes.adoc#vector-index-providers[]. + +[[config-vector-dimensions]] +==== `vector.dimensions` +The dimensions of the vectors to be indexed. +For more information, see xref:indexes/semantic-indexes/vector-indexes.adoc#embeddings[]. +This setting can be omitted, and any `LIST` can be indexed and queried, separated by their dimensions, _though only vectors of the same dimension can be compared._ +Setting this value adds additional checks that ensure only vectors with the configured dimensions are indexed, and querying the index with a vector of a different dimensions returns an error. + +[NOTE] +It is recommended to provide dimensions when creating a vector index. + +Accepted values::: `INTEGER` between `1` and `4096` inclusively. +Default value::: None. +The setting was mandatory prior to Neo4j 5.23. + +[[config-vector-similarity-function]] +==== `vector.similarity_function` + +The name of the similarity function used to assess the similarity of two vectors. +To read more about the available similarity functions, see xref:indexes/semantic-indexes/vector-indexes.adoc#similarity-functions[]. + +Accepted values::: `STRING`: `'cosine'`, `'euclidean'`. +Default value::: `'cosine'`. The setting was mandatory prior to Neo4j 5.23. + +[role=label--new-5.23] +[[config-vector-quantization]] +==== `vector.quantization.enabled` + +Quantization is a technique to reduce the size of vector representations. +Enabling quantization can accelerate search performance but can slightly decrease accuracy. +It is recommended to enable quantization on machines with limited memory. +Vector indexes created prior to Neo4j 5.23 have this setting effectively set to `false`. + +Accepted values::: `BOOLEAN`: `true`, `false`. +Default value::: `true` + +[discrete] +[[config-advanced]] +=== Advanced configuration settings + +[role=label--new-5.23] +[[config-vector-hsnw.m]] +==== `vector.hnsw.m` + +The `M` parameter controls the maximum number of connections each node has in the HNSW (Hierarchical Navigable Small Worlds) graph. +Increasing this value may lead to greater accuracy at the expense of increased index population and update times, especially for vectors with high dimensionality. +Vector indexes created prior to Neo4j 5.23 have this setting effectively set to `16`. + +Accepted values::: `INTEGER` between `1` and `512` inclusively. +Default value::: `16` + +[role=label--new-5.23] +[[config-vector-hsnw.ef_construction]] +==== `vector.hnsw.ef_construction` + +The number of nearest neighbors tracked during the insertion of vectors into the HNSW graph. +Increasing this value increases the quality of the index, and may lead to greater accuracy (with diminishing returns) at the expense of increased index population and update times. +Vector indexes created prior to Neo4j 5.23 have this setting effectively set to `100`. + +Accepted values::: `INTEGER` between `1` and `3200` inclusively. +Default value::: `100` + [[query-vector-index]] == Query vector indexes @@ -159,8 +227,8 @@ RETURN movie.title AS title, movie.plot AS plot, score | "Godfather, The" | "The aging patriarch of an organized crime dynasty transfers control of his clandestine empire to his reluctant son." | 1.0 | | "Godfather: Part III, The" | "In the midst of trying to legitimize his business dealings in New York and Italy in 1979, aging Mafia don Michael Corleone seeks to avow for his sins while taking a young protégé under his wing." | 0.9648237228393555 | | "Godfather: Part II, The" | "The early life and career of Vito Corleone in 1920s New York is portrayed while his son, Michael, expands and tightens his grip on his crime syndicate stretching from Lake Tahoe, Nevada to pre-revolution 1958 Cuba." | 0.9547788500785828 | +| "Goodfellas" | "Henry Hill and his friends work their way up through the mob hierarchy." | 0.9300689697265625 | | "Scarface" | "An ambitious and near insanely violent gangster climbs the ladder of success in the mob, but his weaknesses prove to be his downfall." | 0.9367183446884155 | -| "Jane Austen's Mafia!" | "Takeoff on the Godfather with the son of a mafia king taking over for his dying father" | 0.9366795420646667 | +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ---- @@ -238,11 +306,11 @@ SHOW VECTOR INDEXES YIELD * .Result [source, role=queryresult] ---- -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| id | name | state | populationPercent | type | entityType | labelsOrTypes | properties | indexProvider | owningConstraint | lastRead | readCount | trackedSince | options | failureMessage | createStatement | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| 2 | "moviePlots" | "ONLINE" | 100.0 | "VECTOR" | "NODE" | ["Movie"] | ["embedding"] | "vector-2.0" | NULL | 2024-05-07T09:19:09.225Z | 47 | 2024-05-07T08:26:19.072Z | {indexConfig: {`vector.dimensions`: 1536, `vector.similarity_function`: "COSINE"}, indexProvider: "vector-2.0"} | "" | "CREATE VECTOR INDEX `moviePlots` FOR (n:`Movie`) ON (n.`embedding`) OPTIONS {indexConfig: {`vector.dimensions`: 1536,`vector.similarity_function`: 'COSINE'}, indexProvider: 'vector-2.0'}" | -+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| id | name | state | populationPercent | type | entityType | labelsOrTypes | properties | indexProvider | owningConstraint| lastRead | readCount | trackedSince | options | failureMessage | createStatement | ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| 2 | "moviePlots"| "ONLINE" | 100.0 | "VECTOR" | "NODE" | ["Movie"] | ["embedding"] | "vector-2.0" | NULL | 2024-05-07T09:19:09.225Z | 47 | 2024-05-07T08:26:19.072Z | {indexConfig: {indexConfig: {`vector.dimensions`: 1536, `vector.hnsw.m`: 16, `vector.quantization.enabled`: TRUE, `vector.similarity_function`: "COSINE", `vector.hnsw.ef_construction`: 100}, indexProvider: "vector-2.0"}, indexProvider: "vector-2.0"} | "" | "CREATE VECTOR INDEX `moviePlots` FOR (n:`Movie`) ON (n.`embedding`) OPTIONS {indexConfig: {`vector.dimensions`: 1536,`vector.hnsw.ef_construction`: 100,`vector.hnsw.m`: 16,`vector.quantization.enabled`: true,`vector.similarity_function`: 'COSINE'}, indexProvider: 'vector-2.0'}" | ++-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ---- To return only specific details, specify the desired column name(s) after the `YIELD` clause. @@ -367,7 +435,7 @@ Cosine similarity is used when the _angle_ between the vectors is what determine A valid vector for a cosine vector index is when: -* All vector components can be represented finitely in IEEE 754 double precision. +* All vector components can be represented finitely in IEEE 754 double precision.footnote:[link:https://ieeexplore.ieee.org/document/8766229[IEEE Standard for Floating-Point Arithmetic]] * Its {l2-norm} is non-zero and can be represented finitely in IEEE 754 double precision. * The ratio of each vector component with its {l2-norm} can be represented finitely in IEEE 754 single precision. @@ -386,7 +454,7 @@ In the above equation the trigonometric cosine is given by the scalar product of ==== Euclidean similarity is useful when the _distance_ between the vectors is what determines how similar two vectors are. -A valid vector for a Euclidean vector index is when all vector components can be represented finitely in IEEE 754 single precision.footnote:[link:https://ieeexplore.ieee.org/document/8766229[IEEE Standard for Floating-Point Arithmetic]] +A valid vector for a Euclidean vector index is when all vector components can be represented finitely in IEEE 754 single precision. Euclidean interprets the vectors in Cartesian coordinates. The measure is related to the Euclidean distance, i.e., how far two points are from one another. @@ -449,8 +517,6 @@ The requested _k_ nearest neighbors may not be the exact _k_ nearest, but close * Only one vector index can be over a schema. For example, you cannot have one xref:indexes/semantic-indexes/vector-indexes.adoc#similarity-functions[Euclidean] and one xref:indexes/semantic-indexes/vector-indexes.adoc#similarity-functions[cosine] vector index on the same label-property key pair. -* No provided settings or options for tuning the index. - * Changes made within the same transaction are not visible to the index. ==== @@ -463,6 +529,15 @@ The following table lists the known issues and, if fixed, the version in which t |=== | Known issues | Fixed in +| The creation of a vector index using the legacy procedure link:{neo4j-docs-base-uri}/operations-manual/{page-version}/reference/procedures/#procedure_db_index_vector_createnodeindex[`db.index.vector.createNodeIndex`] may fail with an error in Neo4j 5.18 and later if the database was last written to with a version prior to Neo4j 5.11, and the legacy procedure is the first write operation used on the newer version. +In Neo4j 5.20, the error was clarified. +[TIP] +-- +Using the `CREATE VECTOR INDEX` command instead avoids this issue. +If the use of the procedure is unavoidable, performing any other write operation to the database on the newer binary before using the procedure will avoid the issue +-- +| + | Procedure signatures from `SHOW PROCEDURES` will render the vector arguments with a type of `ANY` rather than the semantically correct type of `LIST`. [NOTE] -- @@ -470,11 +545,13 @@ The types are still enforced as `LIST`. -- | +| No provided settings or options for tuning the index. +| Neo4j 5.23 + | Only node vector indexes are supported. | Neo4j 5.18 | Vector indexes cannot be assigned autogenerated names. - | Neo4j 5.15 | There is no Cypher syntax for creating a vector index. diff --git a/modules/ROOT/pages/indexes/syntax.adoc b/modules/ROOT/pages/indexes/syntax.adoc index 1eb27c3c8..baede5cba 100644 --- a/modules/ROOT/pages/indexes/syntax.adoc +++ b/modules/ROOT/pages/indexes/syntax.adoc @@ -207,17 +207,18 @@ ON (r.propertyName) [OPTIONS “{“ option: value[, …] “}”] ---- -Vector indexes have two settings, `vector.dimensions` and `vector.similarity_function`, which have no default values. -As of Neo4j 5.18, they have two index providers available, `vector-2.0` (default) and `vector-1.0`. +As of Neo4j 5.18, vector indexes have two vector index providers available, `vector-2.0` (default) and `vector-1.0`. +For more information, see xref:indexes/semantic-indexes/vector-indexes.adoc#vector-index-providers[Vector index providers for compatibility]. -The `OPTIONS` clause is mandatory when creating a vector index, because it is necessary to configure the `vector.dimensions` and `vector.similarity_function` settings: +For a full list of all vector index settings, see xref:indexes/semantic-indexes/vector-indexes.adoc#configuration-settings[Vector index configuration settings]. +Note that the `OPTIONS` clause was mandatory prior to Neo4j 5.23 because it was necessary to configure the `vector.dimensions` and `vector.similarity_function` settings when creating a vector index. [source,syntax] ---- OPTIONS { indexConfig: { `vector.dimensions`: $dimension, - `vector.similarity_function`: $similarityFunction + `vector.similarity_function`: $similarityFunction } } ---- @@ -225,7 +226,7 @@ OPTIONS { [NOTE] It is not possible to create composite vector indexes on multiple properties. -For more information, see xref:indexes/semantic-indexes/vector-indexes.adoc#indexes-vector-create[Vector indexes - Create and configure vector indexes]. +For more information, see xref:indexes/semantic-indexes/vector-indexes.adoc#create-vector-index[Vector indexes - Create and configure vector indexes]. [[list-index]] == SHOW INDEX From a85c9fef121dfac5d6b37e88f7fc0d4579ae421c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Mon, 19 Aug 2024 13:53:18 +0200 Subject: [PATCH 17/20] Correct documentation on comparing spatial values (#1023) --- .../deprecations-additions-removals-compatibility.adoc | 2 +- modules/ROOT/pages/syntax/operators.adoc | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc index e93567124..cb7621548 100644 --- a/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc +++ b/modules/ROOT/pages/deprecations-additions-removals-compatibility.adoc @@ -2139,7 +2139,7 @@ label:removed[] point({x:0, y:0}) <= point({x:1, y:1}) <= point({x:2, y:2}) ---- a| -The ability to use operators `<`, `<=`, `>`, and `>=` on spatial points is removed. +The ability to use operators `<`, `+<=+`, `>`, or `>=` on spatial points is removed. Instead, use: [source, cypher, role="noheader"] ---- diff --git a/modules/ROOT/pages/syntax/operators.adoc b/modules/ROOT/pages/syntax/operators.adoc index c5e8075cf..b6ce384ab 100644 --- a/modules/ROOT/pages/syntax/operators.adoc +++ b/modules/ROOT/pages/syntax/operators.adoc @@ -359,11 +359,9 @@ The following points give some details on how the comparison is performed. For example, `1 > b` and `1 < b` are both false when b is NaN. * String values are compared for ordering using lexicographic order (e.g. `"x" < "xy"`). * Boolean values are compared for ordering such that `false < true`. -* *Comparison* of spatial values: - ** Point values can only be compared within the same Coordinate Reference System (CRS) -- otherwise, the result will be `null`. - ** For two points `a` and `b` within the same CRS, `a` is considered to be greater than `b` if `a.x > b.x` and `a.y > b.y` (and `a.z > b.z` for 3D points). - ** `a` is considered less than `b` if `a.x < b.x` and `a.y < b.y` (and `a.z < b.z` for 3D points). - ** If none if the above is true, the points are considered incomparable and any comparison operator between them will return `null`. +* Spatial values cannot be compared using the operators `<`, `+<=+`, `>`, or `>=`. +To compare spatial values within a specific range, use either the xref:functions/spatial.adoc#functions-withinBBox[`point.withinBBox()`] or the xref:functions/spatial.adoc#functions-point-wgs84-2d[`point()`] function. + * *Ordering* of spatial values: ** `ORDER BY` requires all values to be orderable. ** Points are ordered after arrays and before temporal types. From 05aca7fe721c36e0e4e3002433d92fc74d35ea8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Mon, 19 Aug 2024 19:40:30 +0200 Subject: [PATCH 18/20] Add information about Text indexes and dictionary variables (#1026) --- .../using-indexes.adoc | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc index cc7b4f263..4969df552 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc @@ -235,7 +235,6 @@ Text indexes do not store `STRING` properties alphabetically, and are instead op That said, if no range index had been present on the name property, the previous query would still have been able to utilize the text index. It would have done so less efficiently than a range index, but it still would have been useful. - For more information about range index ordering, see the section on xref:indexes/search-performance-indexes/using-indexes.adoc#range-index-backed-order-by[Range index-backed ORDER BY]. [TIP] @@ -243,6 +242,28 @@ Text indexes are only used for exact query matches. To perform approximate match For more information about the predicates supported by text indexes, see xref:indexes/search-performance-indexes/managing-indexes.adoc#text-indexes-supported-predicates[Create, show, and delete indexes -> Text indexes: supported predicates]. +[[text-index-dictionary-variables]] +=== Ensuring text index use + +In order for the planner to use text indexes, it must be able to confirm that the properties included in the predicate are `STRING` values. +This is not possible when accessing property values within nodes or relationships, or values within a `MAP`, since Cypher does not store the type information of these values. +To ensure text indexes are used in these cases, the xref:functions/string.adoc#functions-tostring[`toString`] function should be used. + +.Text index not used +[source,cypher] +---- +WITH {name: 'William Shakespeare'} AS varName +MERGE (:PointOfInterest {name:varName.name}) +---- + +.Text index used +[source,cypher] +---- +WITH {name: 'William Shakespeare'} AS varName +MERGE (ws:PointOfInterest {name: toString(varName.name)}) +---- + +For information about how to ensure the use of text indexes when predicates may contain `null` values, see xref:indexes/search-performance-indexes/using-indexes/indexes-and-null[Indexes and `null` values]. [[text-index-string-size]] === Text indexes and `STRING` sizes From bd39e671253a7c0acefd9ff5e364428f46bafbbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jens=20Pryce-=C3=85klundh?= <112686610+JPryce-Aklundh@users.noreply.github.com> Date: Tue, 20 Aug 2024 08:36:52 +0200 Subject: [PATCH 19/20] Add alias for index page (#1029) --- .../indexes/search-performance-indexes/using-indexes.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc b/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc index 4969df552..bcf88382b 100644 --- a/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc +++ b/modules/ROOT/pages/indexes/search-performance-indexes/using-indexes.adoc @@ -1,6 +1,7 @@ :description: Information about how search-performance indexes impact query performance in Neo4j. :test-setup-dump: https://github.com/neo4j-graph-examples/openstreetmap/raw/main/data/openstreetmap-50.dump include::https://raw.githubusercontent.com/neo4j-graphacademy/courses/main/asciidoc/courses/cypher-indexes-constraints/ad.adoc[] +:page-aliases: query-tuning/indexes.adoc = The impact of indexes on query performance @@ -260,7 +261,7 @@ MERGE (:PointOfInterest {name:varName.name}) [source,cypher] ---- WITH {name: 'William Shakespeare'} AS varName -MERGE (ws:PointOfInterest {name: toString(varName.name)}) +MERGE (:PointOfInterest {name: toString(varName.name)}) ---- For information about how to ensure the use of text indexes when predicates may contain `null` values, see xref:indexes/search-performance-indexes/using-indexes/indexes-and-null[Indexes and `null` values]. From dd11ea84bc5ebd035e0db40397ab7bc0912da53e Mon Sep 17 00:00:00 2001 From: Matthew Parnell Date: Tue, 20 Aug 2024 10:58:36 +0100 Subject: [PATCH 20/20] normalise vector index settings achors (#1030) There were a mix of - _ . being used in the new sections, and some omitted parts of the name, and felt a little inconsistent. This changes the new achors such that it would be #config-INDEXSETTING This is similar to how the Neo4j configuration settings are referenced in the operations manual. --- .../pages/indexes/semantic-indexes/vector-indexes.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc b/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc index 6029c675c..13c8334b2 100644 --- a/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc +++ b/modules/ROOT/pages/indexes/semantic-indexes/vector-indexes.adoc @@ -130,7 +130,7 @@ OPTIONS { indexConfig: { For more information about the values accepted by different index providers, see xref:indexes/semantic-indexes/vector-indexes.adoc#vector-index-providers[]. -[[config-vector-dimensions]] +[[config-vector.dimensions]] ==== `vector.dimensions` The dimensions of the vectors to be indexed. For more information, see xref:indexes/semantic-indexes/vector-indexes.adoc#embeddings[]. @@ -144,7 +144,7 @@ Accepted values::: `INTEGER` between `1` and `4096` inclusively. Default value::: None. The setting was mandatory prior to Neo4j 5.23. -[[config-vector-similarity-function]] +[[config-vector.similarity_function]] ==== `vector.similarity_function` The name of the similarity function used to assess the similarity of two vectors. @@ -154,7 +154,7 @@ Accepted values::: `STRING`: `'cosine'`, `'euclidean'`. Default value::: `'cosine'`. The setting was mandatory prior to Neo4j 5.23. [role=label--new-5.23] -[[config-vector-quantization]] +[[config-vector.quantization.enabled]] ==== `vector.quantization.enabled` Quantization is a technique to reduce the size of vector representations. @@ -170,7 +170,7 @@ Default value::: `true` === Advanced configuration settings [role=label--new-5.23] -[[config-vector-hsnw.m]] +[[config-vector.hsnw.m]] ==== `vector.hnsw.m` The `M` parameter controls the maximum number of connections each node has in the HNSW (Hierarchical Navigable Small Worlds) graph. @@ -181,7 +181,7 @@ Accepted values::: `INTEGER` between `1` and `512` inclusively. Default value::: `16` [role=label--new-5.23] -[[config-vector-hsnw.ef_construction]] +[[config-vector.hsnw.ef_construction]] ==== `vector.hnsw.ef_construction` The number of nearest neighbors tracked during the insertion of vectors into the HNSW graph.