From 6b82a114d5d7d6d447e5940065a0950f90c225e2 Mon Sep 17 00:00:00 2001 From: raphael-istari Date: Wed, 29 Oct 2025 20:01:58 -0700 Subject: [PATCH 1/3] Change DQL pages organization --- archived/cloud/advanced-queries.md | 4 +- content-status.md | 748 ------------------ content/{dql => }/clients/_index.md | 3 +- content/{dql => }/clients/csharp.md | 0 content/{dql => }/clients/go.md | 0 content/{dql => }/clients/java.md | 0 .../{dql => }/clients/javascript/_index.md | 0 content/{dql => }/clients/javascript/grpc.md | 0 content/{dql => }/clients/javascript/http.md | 0 content/{dql => }/clients/python.md | 0 content/{dql => }/clients/raw-http.md | 2 +- .../{dql => }/clients/unofficial-clients.md | 0 content/design-concepts/_index.md | 2 +- content/dgraph-glossary.md | 2 +- content/dql/_index.md | 4 +- content/dql/{dql-syntax => }/dql-mutation.md | 10 +- content/dql/{dql-syntax => }/dql-rdf.md | 8 +- content/dql/dql-schema.md | 2 +- content/dql/dql-syntax/_index.md | 13 - content/dql/dql-syntax/to-sort.md.txt | 631 --------------- .../{dql-syntax => }/json-mutation-format.md | 7 +- content/dql/mutations/_index.md | 11 - .../mutations/external-ids-upsert-block.md | 87 -- content/dql/mutations/uid-upsert.md | 210 ----- content/dql/mutations/val-upsert.md | 82 -- content/dql/predicate-indexing.md | 2 +- content/dql/query/_index.md | 15 + .../query}/aggregation.md | 2 +- .../{query-language => dql/query}/alias.md | 0 .../query}/connecting-filters.md | 0 .../{query-language => dql/query}/count.md | 4 +- .../{query-language => dql/query}/debug.md | 0 content/dql/query/directive/_index.md | 33 + .../query/directive}/cascade-directive.md | 6 +- .../query/directive}/groupby.md | 6 +- .../directive}/ignorereflex-directive.md | 6 +- .../query/directive}/normalize-directive.md | 6 +- .../query/directive}/recurse-query.md | 6 +- .../dql/{dql-syntax => query}/dql-query.md | 32 +- .../query}/expand-predicates.md | 2 +- .../{query-language => dql/query}/facets.md | 4 +- .../query}/fragments.md | 0 .../query}/functions.md | 6 +- .../query}/graphql-variables.md | 8 +- .../query}/indexing-custom-tokenizers.md | 0 .../query}/kshortest-path-queries.md | 2 +- .../query}/language-support.md | 2 +- .../query}/math-on-value-variables.md | 0 .../query}/multiple-query-blocks.md | 0 .../query}/pagination.md | 2 +- .../query}/query-variables.md | 0 .../query/running-examples.md} | 0 .../{query-language => dql/query}/sorting.md | 2 +- .../query}/value-variables.md | 2 +- content/dql/tips/index.md | 6 +- content/dql/upserts.md | 433 ++++++++++ content/graphql/schema/directives/_index.md | 2 - content/howto/dql-schema-request.md | 2 +- content/howto/update-dgraph-types.md | 2 +- content/howto/upserts.md | 79 -- content/learn/data-engineer/_index.md | 2 +- .../tutorial-8/index.md | 8 +- content/query-language/_index.md | 9 - scripts/linkcheck.sh | 37 - 64 files changed, 562 insertions(+), 1992 deletions(-) delete mode 100644 content-status.md rename content/{dql => }/clients/_index.md (96%) rename content/{dql => }/clients/csharp.md (100%) rename content/{dql => }/clients/go.md (100%) rename content/{dql => }/clients/java.md (100%) rename content/{dql => }/clients/javascript/_index.md (100%) rename content/{dql => }/clients/javascript/grpc.md (100%) rename content/{dql => }/clients/javascript/http.md (100%) rename content/{dql => }/clients/python.md (100%) rename content/{dql => }/clients/raw-http.md (99%) rename content/{dql => }/clients/unofficial-clients.md (100%) rename content/dql/{dql-syntax => }/dql-mutation.md (97%) rename content/dql/{dql-syntax => }/dql-rdf.md (96%) delete mode 100644 content/dql/dql-syntax/_index.md delete mode 100644 content/dql/dql-syntax/to-sort.md.txt rename content/dql/{dql-syntax => }/json-mutation-format.md (99%) delete mode 100644 content/dql/mutations/_index.md delete mode 100644 content/dql/mutations/external-ids-upsert-block.md delete mode 100644 content/dql/mutations/uid-upsert.md delete mode 100644 content/dql/mutations/val-upsert.md create mode 100644 content/dql/query/_index.md rename content/{query-language => dql/query}/aggregation.md (97%) rename content/{query-language => dql/query}/alias.md (100%) rename content/{query-language => dql/query}/connecting-filters.md (100%) rename content/{query-language => dql/query}/count.md (88%) rename content/{query-language => dql/query}/debug.md (100%) create mode 100644 content/dql/query/directive/_index.md rename content/{query-language => dql/query/directive}/cascade-directive.md (99%) rename content/{query-language => dql/query/directive}/groupby.md (97%) rename content/{query-language => dql/query/directive}/ignorereflex-directive.md (88%) rename content/{query-language => dql/query/directive}/normalize-directive.md (95%) rename content/{query-language => dql/query/directive}/recurse-query.md (95%) rename content/dql/{dql-syntax => query}/dql-query.md (81%) rename content/{query-language => dql/query}/expand-predicates.md (95%) rename content/{query-language => dql/query}/facets.md (97%) rename content/{query-language => dql/query}/fragments.md (100%) rename content/{query-language => dql/query}/functions.md (98%) rename content/{query-language => dql/query}/graphql-variables.md (92%) rename content/{query-language => dql/query}/indexing-custom-tokenizers.md (100%) rename content/{query-language => dql/query}/kshortest-path-queries.md (99%) rename content/{query-language => dql/query}/language-support.md (96%) rename content/{query-language => dql/query}/math-on-value-variables.md (100%) rename content/{query-language => dql/query}/multiple-query-blocks.md (100%) rename content/{query-language => dql/query}/pagination.md (98%) rename content/{query-language => dql/query}/query-variables.md (100%) rename content/{query-language/graphql-fundamentals.md => dql/query/running-examples.md} (100%) rename content/{query-language => dql/query}/sorting.md (96%) rename content/{query-language => dql/query}/value-variables.md (98%) create mode 100644 content/dql/upserts.md delete mode 100644 content/howto/upserts.md delete mode 100644 content/query-language/_index.md delete mode 100644 scripts/linkcheck.sh diff --git a/archived/cloud/advanced-queries.md b/archived/cloud/advanced-queries.md index f617ad8f..9ab0dcde 100644 --- a/archived/cloud/advanced-queries.md +++ b/archived/cloud/advanced-queries.md @@ -14,10 +14,10 @@ database operations. Advanced users can use DQL to send queries and mutations to Dgraph Cloud's HTTP or gRPC endpoints using the Dgraph client libraries. To learn more about the Dgraph client libraries, see the [client library documentation](https://dgraph.io/docs/clients/). To learn more -about DQL, see [DQL Fundamentals](https://dgraph.io/docs/query-language/graphql-fundamentals/).. +about DQL, see [DQL Fundamentals]({{< relref "graphql-fundamentals.md">}}).. If you are getting started with Dgraph Cloud, you should probably start out by -using Dgraph's [GraphQL API](https://dgraph.io/docs/graphql/overview) instead. +using Dgraph's [GraphQL API]({{< relref "graphql/_index.md">}) instead. Dgraph's GraphQL API lets you quickly use Dgraph Cloud before moving on to the advanced features available using DQL. diff --git a/content-status.md b/content-status.md deleted file mode 100644 index 15c304b1..00000000 --- a/content-status.md +++ /dev/null @@ -1,748 +0,0 @@ -# Content Status Evaluation - -This document evaluates all pages in the content directory for open source documentation quality. Each page is scored 1-4 (4 being best) based on technical accuracy, clarity, absence of marketing language, and completeness of instructions. - -## Evaluation Criteria: -- **Score 4**: Excellent technical documentation with clear instructions, code examples, and no marketing language -- **Score 3**: Good documentation with minor issues or missing elements -- **Score 2**: Adequate documentation but needs significant improvement -- **Score 1**: Poor documentation with major issues or heavy marketing content - ---- - -## Pages (Sorted by Score: Lowest to Highest) - -### Score 1 (Needs Major Improvement) - -**content/_index.md** - Score: 1 - Marketing-heavy landing page with promotional language; convert to technical overview with clear navigation to documentation sections. - -**content/learn/developer/sample-apps/devjokes.md** - Score: 1 - Marketing-focused sample app showcase; rewrite as technical tutorial with step-by-step implementation guide. - -**content/learn/developer/sample-apps/pokedex.md** - Score: 1 - Marketing showcase content; convert to technical tutorial with code examples and deployment instructions. - -**content/learn/developer/sample-apps/surveyo.md** - Score: 1 - Marketing showcase; rewrite as technical implementation guide with architecture details and code samples. - -**content/learn/developer/sample-apps/todos.md** - Score: 1 - Marketing showcase; convert to technical tutorial with complete code examples and setup instructions. - -**content/learn/developer/sample-apps/charts.md** - Score: 1 - Marketing content; rewrite as technical documentation with implementation details and code examples. - -**content/releases/index.md** - Score: 1 - Marketing release notes; convert to technical changelog with API changes, breaking changes, and migration guides. - -### Score 2 (Needs Significant Improvement) - -**content/dgraph-overview.md** - Score: 2 - Mix of marketing and technical content; separate into pure technical overview and move marketing to separate page. - -**content/graphql/_index.md** - Score: 2 - Contains marketing language; rewrite to focus on technical capabilities and API reference links. - -**content/ratel/_index.md** - Score: 4 - Excellent Ratel UI overview with clear organization and comprehensive coverage of UI functionality. - -**content/enterprise-features/_index.md** - Score: 2 - Marketing-heavy enterprise features overview; convert to technical feature documentation with implementation details. - -**content/learn/_index.md** - Score: 2 - Marketing-focused learning hub; rewrite as technical learning path with clear prerequisites and learning objectives. - -**content/howto/_index.md** - Score: 2 - Brief overview without clear organization; expand with technical categorization and clear navigation structure. - -**content/design-concepts/_index.md** - Score: 2 - High-level overview without technical depth; add technical implementation details and architecture diagrams. - -**content/deploy/_index.md** - Score: 2 - Marketing language mixed with technical content; separate into pure technical deployment guide. - -**content/migration/_index.md** - Score: 2 - Brief overview; expand with detailed migration strategies, tools, and step-by-step procedures. - -**content/query-language/_index.md** - Score: 2 - Marketing language present; rewrite as technical query language reference with syntax overview. - -**content/dql/_index.md** - Score: 2 - Marketing language mixed with technical content; convert to pure technical DQL reference documentation. - -**content/graphql-dql/_index.md** - Score: 2 - Marketing-focused interoperability overview; rewrite as technical integration guide with code examples. - -**content/enterprise-features/license.md** - Score: 2 - Marketing-focused licensing information; convert to technical licensing documentation with clear terms and restrictions. - -**content/enterprise-features/multitenancy.md** - Score: 2 - Marketing language present; rewrite as technical multitenancy implementation guide with configuration examples. - -**content/enterprise-features/access-control-lists.md** - Score: 2 - Marketing language mixed with technical content; separate into pure technical ACL implementation guide. - -**content/enterprise-features/audit-logs.md** - Score: 2 - Marketing language present; rewrite as technical audit logging configuration and implementation guide. - -**content/enterprise-features/binary-backups.md** - Score: 2 - Marketing language mixed with technical content; convert to technical backup and restore procedures. - -**content/enterprise-features/change-data-capture.md** - Score: 2 - Marketing language present; rewrite as technical CDC implementation guide with configuration examples. - -**content/enterprise-features/encryption-at-rest.md** - Score: 2 - Marketing language mixed with technical content; convert to technical encryption configuration guide. - -**content/enterprise-features/learner-nodes.md** - Score: 2 - Marketing language present; rewrite as technical learner node configuration and management guide. - -**content/enterprise-features/lsbackup.md** - Score: 2 - Marketing language mixed with technical content; convert to technical backup tool documentation with usage examples. - -**content/deploy/installation/_index.md** - Score: 2 - Marketing language present; rewrite as technical installation guide with clear prerequisites and system requirements. - -**content/deploy/installation/download.md** - Score: 2 - Marketing language mixed with technical content; convert to technical download and installation procedures. - -**content/deploy/installation/lambda-server.md** - Score: 2 - Marketing language present; rewrite as technical Lambda server configuration and deployment guide. - -**content/deploy/installation/production-checklist.md** - Score: 2 - Marketing language mixed with technical content; convert to technical production deployment checklist with specific configurations. - -**content/deploy/installation/single-host-setup.md** - Score: 2 - Marketing language present; rewrite as technical single-host deployment guide with detailed configuration steps. - -**content/deploy/installation/kubernetes/_index.md** - Score: 2 - Marketing language present; rewrite as technical Kubernetes deployment guide with YAML examples. - -**content/deploy/installation/kubernetes/cluster-types.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Kubernetes cluster configuration guide. - -**content/deploy/installation/kubernetes/ha-cluster.md** - Score: 2 - Marketing language present; rewrite as technical high-availability Kubernetes deployment guide. - -**content/deploy/installation/kubernetes/monitoring-cluster.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Kubernetes monitoring setup guide. - -**content/deploy/installation/kubernetes/single-server-cluster.md** - Score: 2 - Marketing language present; rewrite as technical single-server Kubernetes deployment guide. - -**content/deploy/admin/_index.md** - Score: 2 - Marketing language present; rewrite as technical administration guide with clear management procedures. - -**content/deploy/admin/data-compression.md** - Score: 2 - Marketing language mixed with technical content; convert to technical compression configuration guide. - -**content/deploy/admin/dgraph-administration.md** - Score: 2 - Marketing language present; rewrite as technical administration procedures with command examples. - -**content/deploy/admin/log-format.md** - Score: 2 - Marketing language mixed with technical content; convert to technical logging configuration guide. - -**content/deploy/admin/metrics.md** - Score: 2 - Marketing language present; rewrite as technical metrics collection and monitoring guide. - -**content/deploy/admin/tracing.md** - Score: 2 - Marketing language mixed with technical content; convert to technical tracing configuration and analysis guide. - -**content/deploy/cli-command-reference.md** - Score: 2 - Marketing language present; rewrite as technical CLI reference with complete command documentation. - -**content/deploy/cluster-checklist.md** - Score: 2 - Marketing language mixed with technical content; convert to technical cluster deployment checklist. - -**content/deploy/cluster-setup.md** - Score: 2 - Marketing language present; rewrite as technical cluster setup guide with configuration examples. - -**content/deploy/config.md** - Score: 2 - Marketing language mixed with technical content; convert to technical configuration reference with all options documented. - -**content/deploy/decrypt.md** - Score: 2 - Marketing language present; rewrite as technical decryption tool documentation with usage examples. - -**content/deploy/dgraph-alpha.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Alpha server configuration guide. - -**content/deploy/dgraph-architecture.md** - Score: 2 - Marketing language present; rewrite as technical architecture documentation with detailed component descriptions. - -**content/deploy/dgraph-zero.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Zero server configuration guide. - -**content/deploy/monitoring.md** - Score: 2 - Marketing language present; rewrite as technical monitoring setup guide with specific tools and configurations. - -**content/deploy/security/_index.md** - Score: 2 - Marketing language present; rewrite as technical security configuration guide with implementation details. - -**content/deploy/security/ports-usage.md** - Score: 2 - Marketing language mixed with technical content; convert to technical port configuration reference. - -**content/deploy/security/tls-configuration.md** - Score: 2 - Marketing language present; rewrite as technical TLS configuration guide with certificate setup. - -**content/deploy/troubleshooting.md** - Score: 2 - Marketing language mixed with technical content; convert to technical troubleshooting guide with specific solutions. - -**content/design-concepts/acl-concept.md** - Score: 2 - Marketing language present; rewrite as technical ACL concept documentation with implementation details. - -**content/design-concepts/badger-concept.md** - Score: 2 - Marketing language mixed with technical content; convert to technical BadgerDB integration documentation. - -**content/design-concepts/clients-concept.md** - Score: 2 - Marketing language present; rewrite as technical client integration guide with code examples. - -**content/design-concepts/consistency-model.md** - Score: 2 - Marketing language mixed with technical content; convert to technical consistency model documentation. - -**content/design-concepts/discovery-concept.md** - Score: 2 - Marketing language present; rewrite as technical service discovery documentation. - -**content/design-concepts/dql-concept.md** - Score: 2 - Marketing language mixed with technical content; convert to technical DQL language documentation. - -**content/design-concepts/dql-graphql-layering-concept.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL-DQL integration documentation. - -**content/design-concepts/facets-concept.md** - Score: 2 - Marketing language mixed with technical content; convert to technical facets implementation guide. - -**content/design-concepts/graphql-concept.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL API documentation. - -**content/design-concepts/group-concept.md** - Score: 2 - Marketing language mixed with technical content; convert to technical group management documentation. - -**content/design-concepts/index-tokenize-concept.md** - Score: 2 - Marketing language present; rewrite as technical indexing and tokenization guide. - -**content/design-concepts/lambda-concept.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Lambda function documentation. - -**content/design-concepts/minimizing-network-calls.md** - Score: 2 - Marketing language present; rewrite as technical network optimization guide. - -**content/design-concepts/namespace-tenant-concept.md** - Score: 2 - Marketing language mixed with technical content; convert to technical namespace and tenant documentation. - -**content/design-concepts/network-call-minimization-concept.md** - Score: 2 - Marketing language present; rewrite as technical network optimization documentation. - -**content/design-concepts/posting-list-concept.md** - Score: 2 - Marketing language mixed with technical content; convert to technical posting list implementation guide. - -**content/design-concepts/protocol-buffers-concept.md** - Score: 2 - Marketing language present; rewrite as technical Protocol Buffers integration documentation. - -**content/design-concepts/queries-process.md** - Score: 2 - Marketing language mixed with technical content; convert to technical query processing documentation. - -**content/design-concepts/raft.md** - Score: 2 - Marketing language present; rewrite as technical Raft consensus documentation. - -**content/design-concepts/relationships-concept.md** - Score: 2 - Marketing language mixed with technical content; convert to technical relationship modeling guide. - -**content/design-concepts/replication-concept.md** - Score: 2 - Marketing language present; rewrite as technical replication configuration documentation. - -**content/design-concepts/transaction-mutation-concept.md** - Score: 2 - Marketing language mixed with technical content; convert to technical transaction and mutation documentation. - -**content/design-concepts/transactions-concept.md** - Score: 2 - Marketing language present; rewrite as technical transaction model documentation. - -**content/design-concepts/wal-memtable-concept.md** - Score: 2 - Marketing language mixed with technical content; convert to technical WAL and memtable documentation. - -**content/design-concepts/workers-concept.md** - Score: 2 - Marketing language present; rewrite as technical worker process documentation. - -**content/dql/clients/_index.md** - Score: 2 - Marketing language present; rewrite as technical client library overview with implementation examples. - -**content/dql/clients/csharp.md** - Score: 2 - Marketing language mixed with technical content; convert to technical C# client documentation with code examples. - -**content/dql/clients/go.md** - Score: 2 - Marketing language present; rewrite as technical Go client documentation with usage examples. - -**content/dql/clients/java.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Java client documentation with code samples. - -**content/dql/clients/javascript/_index.md** - Score: 2 - Marketing language present; rewrite as technical JavaScript client overview with implementation guide. - -**content/dql/clients/javascript/grpc.md** - Score: 2 - Marketing language mixed with technical content; convert to technical gRPC JavaScript client documentation. - -**content/dql/clients/javascript/http.md** - Score: 2 - Marketing language present; rewrite as technical HTTP JavaScript client documentation. - -**content/dql/clients/python.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Python client documentation with examples. - -**content/dql/clients/raw-http.md** - Score: 2 - Marketing language present; rewrite as technical raw HTTP client documentation with request examples. - -**content/dql/clients/unofficial-clients.md** - Score: 2 - Marketing language mixed with technical content; convert to technical community client documentation. - -**content/dql/dql-get-started.md** - Score: 2 - Marketing language present; rewrite as technical DQL quick start guide with complete examples. - -**content/dql/dql-schema.md** - Score: 2 - Marketing language mixed with technical content; convert to technical schema definition documentation. - -**content/dql/dql-syntax/_index.md** - Score: 2 - Marketing language present; rewrite as technical DQL syntax reference with complete grammar. - -**content/dql/dql-syntax/dql-mutation.md** - Score: 2 - Marketing language mixed with technical content; convert to technical mutation syntax documentation. - -**content/dql/dql-syntax/dql-query.md** - Score: 2 - Marketing language present; rewrite as technical query syntax documentation with examples. - -**content/dql/dql-syntax/dql-rdf.md** - Score: 2 - Marketing language mixed with technical content; convert to technical RDF format documentation. - -**content/dql/dql-syntax/json-mutation-format.md** - Score: 2 - Marketing language present; rewrite as technical JSON mutation format documentation. - -**content/dql/mutations/_index.md** - Score: 2 - Marketing language present; rewrite as technical mutation operations overview. - -**content/dql/mutations/external-ids-upsert-block.md** - Score: 2 - Marketing language mixed with technical content; convert to technical upsert operations documentation. - -**content/dql/mutations/uid-upsert.md** - Score: 2 - Marketing language present; rewrite as technical UID upsert documentation with examples. - -**content/dql/mutations/val-upsert.md** - Score: 2 - Marketing language mixed with technical content; convert to technical value upsert documentation. - -**content/dql/predicate-indexing.md** - Score: 2 - Marketing language present; rewrite as technical indexing configuration guide. - -**content/dql/tips/index.md** - Score: 2 - Marketing language mixed with technical content; convert to technical DQL best practices guide. - -**content/graphql-dql/dql-for-graphql.md** - Score: 2 - Marketing language present; rewrite as technical DQL integration guide for GraphQL. - -**content/graphql-dql/graphql-data-loading.md** - Score: 2 - Marketing language mixed with technical content; convert to technical data loading procedures. - -**content/graphql-dql/graphql-data-migration.md** - Score: 2 - Marketing language present; rewrite as technical migration procedures with step-by-step instructions. - -**content/graphql-dql/graphql-dgraph.md** - Score: 2 - Marketing language mixed with technical content; convert to technical GraphQL-Dgraph integration documentation. - -**content/graphql-dql/graphql-dql-schema.md** - Score: 2 - Marketing language present; rewrite as technical schema mapping documentation. - -**content/graphql/admin/index.md** - Score: 2 - Marketing language mixed with technical content; convert to technical GraphQL administration guide. - -**content/graphql/custom/_index.md** - Score: 2 - Marketing language present; rewrite as technical custom resolver overview. - -**content/graphql/custom/custom-dql.md** - Score: 2 - Marketing language mixed with technical content; convert to technical custom DQL resolver documentation. - -**content/graphql/custom/custom-overview.md** - Score: 2 - Marketing language present; rewrite as technical custom resolver implementation guide. - -**content/graphql/custom/directive.md** - Score: 2 - Marketing language mixed with technical content; convert to technical custom directive documentation. - -**content/graphql/custom/field.md** - Score: 2 - Marketing language present; rewrite as technical custom field resolver documentation. - -**content/graphql/custom/mutation.md** - Score: 2 - Marketing language mixed with technical content; convert to technical custom mutation resolver documentation. - -**content/graphql/custom/query.md** - Score: 2 - Marketing language present; rewrite as technical custom query resolver documentation. - -**content/graphql/federation/index.md** - Score: 2 - Marketing language mixed with technical content; convert to technical GraphQL federation implementation guide. - -**content/graphql/graphql-clients/_index.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL client overview. - -**content/graphql/graphql-clients/endpoint/_index.md** - Score: 2 - Marketing language mixed with technical content; convert to technical GraphQL endpoint documentation. - -**content/graphql/graphql-clients/endpoint/graphql-get-request.md** - Score: 2 - Marketing language present; rewrite as technical GET request documentation. - -**content/graphql/graphql-clients/endpoint/graphql-request.md** - Score: 2 - Marketing language mixed with technical content; convert to technical GraphQL request documentation. - -**content/graphql/graphql-clients/endpoint/graphql-response.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL response documentation. - -**content/graphql/graphql-clients/graphql-ide.md** - Score: 2 - Marketing language mixed with technical content; convert to technical GraphQL IDE integration guide. - -**content/graphql/graphql-clients/graphql-ui.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL UI documentation. - -**content/graphql/lambda/_index.md** - Score: 2 - Marketing language present; rewrite as technical Lambda resolver overview. - -**content/graphql/lambda/field.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Lambda field resolver documentation. - -**content/graphql/lambda/lambda-overview.md** - Score: 2 - Marketing language present; rewrite as technical Lambda resolver implementation guide. - -**content/graphql/lambda/mutation.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Lambda mutation resolver documentation. - -**content/graphql/lambda/query.md** - Score: 2 - Marketing language present; rewrite as technical Lambda query resolver documentation. - -**content/graphql/lambda/webhook.md** - Score: 2 - Marketing language mixed with technical content; convert to technical webhook integration documentation. - -**content/graphql/mutations/_index.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL mutations overview. - -**content/graphql/mutations/add.md** - Score: 2 - Marketing language mixed with technical content; convert to technical add mutation documentation. - -**content/graphql/mutations/deep.md** - Score: 2 - Marketing language present; rewrite as technical deep mutation documentation. - -**content/graphql/mutations/delete.md** - Score: 2 - Marketing language mixed with technical content; convert to technical delete mutation documentation. - -**content/graphql/mutations/mutations-overview.md** - Score: 2 - Marketing language present; rewrite as technical mutations reference guide. - -**content/graphql/mutations/update.md** - Score: 2 - Marketing language mixed with technical content; convert to technical update mutation documentation. - -**content/graphql/mutations/upsert.md** - Score: 2 - Marketing language present; rewrite as technical upsert mutation documentation. - -**content/graphql/queries/_index.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL queries overview. - -**content/graphql/queries/aggregate.md** - Score: 2 - Marketing language mixed with technical content; convert to technical aggregation query documentation. - -**content/graphql/queries/and-or-not.md** - Score: 2 - Marketing language present; rewrite as technical logical operator documentation. - -**content/graphql/queries/cached-results.md** - Score: 2 - Marketing language mixed with technical content; convert to technical query caching documentation. - -**content/graphql/queries/cascade.md** - Score: 2 - Marketing language present; rewrite as technical cascade directive documentation. - -**content/graphql/queries/order-page.md** - Score: 2 - Marketing language mixed with technical content; convert to technical ordering and pagination documentation. - -**content/graphql/queries/persistent-queries.md** - Score: 2 - Marketing language present; rewrite as technical persistent queries documentation. - -**content/graphql/queries/queries-overview.md** - Score: 2 - Marketing language present; rewrite as technical queries reference guide. - -**content/graphql/queries/search-filtering.md** - Score: 2 - Marketing language mixed with technical content; convert to technical search and filtering documentation. - -**content/graphql/queries/skip-include.md** - Score: 2 - Marketing language present; rewrite as technical skip/include directive documentation. - -**content/graphql/queries/vector-similarity.md** - Score: 2 - Marketing language mixed with technical content; convert to technical vector similarity documentation. - -**content/graphql/quick-start/index.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL quick start guide with complete examples. - -**content/graphql/schema/_index.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL schema overview. - -**content/graphql/schema/dgraph-schema.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Dgraph schema documentation. - -**content/graphql/schema/directives/_index.md** - Score: 2 - Marketing language present; rewrite as technical directives overview. - -**content/graphql/schema/directives/auth.md** - Score: 2 - Marketing language mixed with technical content; convert to technical authentication directive documentation. - -**content/graphql/schema/directives/deprecated.md** - Score: 2 - Marketing language present; rewrite as technical deprecated directive documentation. - -**content/graphql/schema/directives/directive-dgraph.md** - Score: 2 - Marketing language mixed with technical content; convert to technical @dgraph directive documentation. - -**content/graphql/schema/directives/directive-withsubscription.md** - Score: 2 - Marketing language present; rewrite as technical subscription directive documentation. - -**content/graphql/schema/directives/embedding.md** - Score: 2 - Marketing language mixed with technical content; convert to technical embedding directive documentation. - -**content/graphql/schema/directives/generate.md** - Score: 2 - Marketing language present; rewrite as technical generate directive documentation. - -**content/graphql/schema/directives/ids.md** - Score: 2 - Marketing language mixed with technical content; convert to technical IDs directive documentation. - -**content/graphql/schema/directives/search.md** - Score: 2 - Marketing language present; rewrite as technical search directive documentation. - -**content/graphql/schema/documentation.md** - Score: 2 - Marketing language mixed with technical content; convert to technical schema documentation guide. - -**content/graphql/schema/graph-links.md** - Score: 2 - Marketing language present; rewrite as technical graph links documentation. - -**content/graphql/schema/migration.md** - Score: 2 - Marketing language mixed with technical content; convert to technical schema migration documentation. - -**content/graphql/schema/reserved.md** - Score: 2 - Marketing language present; rewrite as technical reserved schema documentation. - -**content/graphql/schema/types.md** - Score: 2 - Marketing language mixed with technical content; convert to technical GraphQL types documentation. - -**content/graphql/security/RBAC-rules.md** - Score: 2 - Marketing language present; rewrite as technical RBAC configuration guide. - -**content/graphql/security/_index.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL security overview. - -**content/graphql/security/auth-tips.md** - Score: 2 - Marketing language mixed with technical content; convert to technical authentication best practices guide. - -**content/graphql/security/cors.md** - Score: 2 - Marketing language present; rewrite as technical CORS configuration documentation. - -**content/graphql/security/graphtraversal-rules.md** - Score: 2 - Marketing language mixed with technical content; convert to technical graph traversal security documentation. - -**content/graphql/security/jwt.md** - Score: 2 - Marketing language present; rewrite as technical JWT authentication documentation. - -**content/graphql/security/mutations.md** - Score: 2 - Marketing language mixed with technical content; convert to technical mutation security documentation. - -**content/graphql/subscriptions/index.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL subscriptions documentation. - -**content/howto/commandline/_index.md** - Score: 2 - Marketing language present; rewrite as technical CLI tools overview. - -**content/howto/commandline/about-cli.md** - Score: 2 - Marketing language mixed with technical content; convert to technical CLI tool documentation. - -**content/howto/commandline/create-cli.md** - Score: 2 - Marketing language present; rewrite as technical CLI creation guide. - -**content/howto/completion.md** - Score: 2 - Marketing language mixed with technical content; convert to technical shell completion setup guide. - -**content/howto/concurrent-modification-java-multithreaded.md** - Score: 2 - Marketing language present; rewrite as technical Java concurrency guide. - -**content/howto/dgraph-sentry-integration.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Sentry integration documentation. - -**content/howto/dql-schema-request.md** - Score: 2 - Marketing language present; rewrite as technical schema request documentation. - -**content/howto/drop-data.md** - Score: 2 - Marketing language mixed with technical content; convert to technical data deletion procedures. - -**content/howto/exportdata/_index.md** - Score: 2 - Marketing language present; rewrite as technical data export overview. - -**content/howto/exportdata/about-export.md** - Score: 2 - Marketing language mixed with technical content; convert to technical export procedures documentation. - -**content/howto/exportdata/export-data-cloud.md** - Score: 2 - Marketing language present; rewrite as technical cloud export procedures. - -**content/howto/exportdata/export-data.md** - Score: 2 - Marketing language mixed with technical content; convert to technical data export documentation. - -**content/howto/importdata/_index.md** - Score: 2 - Marketing language present; rewrite as technical data import overview. - -**content/howto/importdata/about_import.md** - Score: 2 - Marketing language mixed with technical content; convert to technical import procedures documentation. - -**content/howto/importdata/bulk-loader.md** - Score: 2 - Marketing language present; rewrite as technical bulk loader documentation. - -**content/howto/importdata/live-loader.md** - Score: 2 - Marketing language mixed with technical content; convert to technical live loader documentation. - -**content/howto/jepsen-tests.md** - Score: 2 - Marketing language present; rewrite as technical Jepsen testing documentation. - -**content/howto/load-balancing-nginx.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Nginx load balancing configuration. - -**content/howto/login-system.md** - Score: 2 - Marketing language present; rewrite as technical authentication system implementation guide. - -**content/howto/retrieving-debug-information.md** - Score: 2 - Marketing language mixed with technical content; convert to technical debugging procedures documentation. - -**content/howto/update-dgraph-types.md** - Score: 2 - Marketing language present; rewrite as technical schema update procedures. - -**content/howto/upserts.md** - Score: 2 - Marketing language mixed with technical content; convert to technical upsert operations documentation. - -**content/howto/using-debug-tool.md** - Score: 2 - Marketing language present; rewrite as technical debug tool usage guide. - -**content/howto/using-increment-tool.md** - Score: 2 - Marketing language mixed with technical content; convert to technical increment tool documentation. - -**content/learn/administrator/_index.md** - Score: 2 - Marketing language present; rewrite as technical administrator learning path. - -**content/learn/data-engineer/_index.md** - Score: 2 - Marketing language present; rewrite as technical data engineer learning path. - -**content/learn/data-engineer/data-model-101/_index.md** - Score: 2 - Marketing language present; rewrite as technical data modeling tutorial overview. - -**content/learn/data-engineer/data-model-101/01-dm-101-introduction.md** - Score: 2 - Marketing language mixed with technical content; convert to technical data modeling introduction. - -**content/learn/data-engineer/data-model-101/02-relational-data-model.md** - Score: 2 - Marketing language present; rewrite as technical relational data model tutorial. - -**content/learn/data-engineer/data-model-101/03-graph-data-model.md** - Score: 2 - Marketing language mixed with technical content; convert to technical graph data model tutorial. - -**content/learn/data-engineer/data-model-101/04-rel-query.md** - Score: 2 - Marketing language present; rewrite as technical relational query tutorial. - -**content/learn/data-engineer/data-model-101/05-graph-query.md** - Score: 2 - Marketing language mixed with technical content; convert to technical graph query tutorial. - -**content/learn/data-engineer/data-model-101/06-dm-101-conclusion.md** - Score: 2 - Marketing language present; rewrite as technical data modeling conclusion. - -**content/learn/data-engineer/get-started-with-dgraph/_index.md** - Score: 2 - Marketing language present; rewrite as technical Dgraph tutorial overview. - -**content/learn/data-engineer/get-started-with-dgraph/tutorial-1/index.md** - Score: 2 - Marketing language mixed with technical content; convert to technical tutorial with step-by-step instructions. - -**content/learn/data-engineer/get-started-with-dgraph/tutorial-2/index.md** - Score: 2 - Marketing language present; rewrite as technical tutorial with complete examples. - -**content/learn/data-engineer/get-started-with-dgraph/tutorial-3/index.md** - Score: 2 - Marketing language mixed with technical content; convert to technical tutorial with implementation details. - -**content/learn/data-engineer/get-started-with-dgraph/tutorial-4/index.md** - Score: 2 - Marketing language present; rewrite as technical tutorial with code examples. - -**content/learn/data-engineer/get-started-with-dgraph/tutorial-5/index.md** - Score: 2 - Marketing language mixed with technical content; convert to technical tutorial with practical exercises. - -**content/learn/data-engineer/get-started-with-dgraph/tutorial-6/index.md** - Score: 2 - Marketing language present; rewrite as technical tutorial with advanced concepts. - -**content/learn/data-engineer/get-started-with-dgraph/tutorial-7/index.md** - Score: 2 - Marketing language mixed with technical content; convert to technical tutorial with real-world examples. - -**content/learn/data-engineer/get-started-with-dgraph/tutorial-8/index.md** - Score: 2 - Marketing language present; rewrite as technical tutorial with production considerations. - -**content/learn/developer/_index.md** - Score: 2 - Marketing language present; rewrite as technical developer learning path. - -**content/learn/developer/react/_index.md** - Score: 2 - Marketing language present; rewrite as technical React integration tutorial overview. - -**content/learn/developer/react/graphql/_index.md** - Score: 2 - Marketing language mixed with technical content; convert to technical GraphQL React tutorial overview. - -**content/learn/developer/react/graphql/design-app-schema.md** - Score: 2 - Marketing language present; rewrite as technical schema design tutorial. - -**content/learn/developer/react/graphql/graphql-operations.md** - Score: 2 - Marketing language mixed with technical content; convert to technical GraphQL operations tutorial. - -**content/learn/developer/react/graphql/graphql-schema.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL schema tutorial. - -**content/learn/developer/react/graphql/load-schema-to-dgraph-cloud.md** - Score: 2 - Marketing language mixed with technical content; convert to technical schema deployment tutorial. - -**content/learn/developer/react/graphql/react-graphql-mutations.md** - Score: 2 - Marketing language present; rewrite as technical React GraphQL mutations tutorial. - -**content/learn/developer/react/graphql/react-graphql-queries.md** - Score: 2 - Marketing language mixed with technical content; convert to technical React GraphQL queries tutorial. - -**content/learn/developer/react/react-conclusion.md** - Score: 2 - Marketing language present; rewrite as technical React tutorial conclusion. - -**content/learn/developer/react/react-introduction.md** - Score: 2 - Marketing language mixed with technical content; convert to technical React integration introduction. - -**content/learn/developer/react/react-ui/_index.md** - Score: 2 - Marketing language present; rewrite as technical React UI tutorial overview. - -**content/learn/developer/react/react-ui/connect-to-dgraph-cloud.md** - Score: 2 - Marketing language mixed with technical content; convert to technical cloud connection tutorial. - -**content/learn/developer/react/react-ui/react-app-boiler-plate.md** - Score: 2 - Marketing language present; rewrite as technical React boilerplate tutorial. - -**content/learn/developer/react/react-ui/react-routing.md** - Score: 2 - Marketing language mixed with technical content; convert to technical React routing tutorial. - -**content/learn/developer/react/react-ui/react-ui-graphql-mutations.md** - Score: 2 - Marketing language present; rewrite as technical React UI mutations tutorial. - -**content/learn/developer/react/react-ui/react-ui-graphql-queries.md** - Score: 2 - Marketing language mixed with technical content; convert to technical React UI queries tutorial. - -**content/learn/developer/react/react-ui/tech-stack.md** - Score: 2 - Marketing language present; rewrite as technical tech stack documentation. - -**content/learn/developer/sample-apps/_index.md** - Score: 2 - Marketing language present; rewrite as technical sample applications overview. - -**content/learn/developer/todo-app-tutorial/_index.md** - Score: 2 - Marketing language present; rewrite as technical todo app tutorial overview. - -**content/learn/developer/todo-app-tutorial/todo-UI.md** - Score: 2 - Marketing language mixed with technical content; convert to technical UI implementation tutorial. - -**content/learn/developer/todo-app-tutorial/todo-auth-rules.md** - Score: 2 - Marketing language present; rewrite as technical authentication tutorial. - -**content/learn/developer/todo-app-tutorial/todo-auth0-jwt.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Auth0 integration tutorial. - -**content/learn/developer/todo-app-tutorial/todo-deploy.md** - Score: 2 - Marketing language present; rewrite as technical deployment tutorial. - -**content/learn/developer/todo-app-tutorial/todo-firebase-jwt.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Firebase integration tutorial. - -**content/learn/developer/todo-app-tutorial/todo-overview.md** - Score: 2 - Marketing language present; rewrite as technical todo app overview. - -**content/learn/developer/todo-app-tutorial/todo-schema-design.md** - Score: 2 - Marketing language mixed with technical content; convert to technical schema design tutorial. - -**content/migration/about-data-migration.md** - Score: 2 - Marketing language present; rewrite as technical data migration procedures. - -**content/migration/loading-csv-data.md** - Score: 2 - Marketing language mixed with technical content; convert to technical CSV data loading procedures. - -**content/migration/migrate-tool.md** - Score: 2 - Marketing language present; rewrite as technical migration tool documentation. - -**content/query-language/aggregation.md** - Score: 2 - Marketing language mixed with technical content; convert to technical aggregation functions documentation. - -**content/query-language/alias.md** - Score: 2 - Marketing language present; rewrite as technical alias usage documentation. - -**content/query-language/cascade-directive.md** - Score: 2 - Marketing language mixed with technical content; convert to technical cascade directive documentation. - -**content/query-language/connecting-filters.md** - Score: 2 - Marketing language present; rewrite as technical filter connection documentation. - -**content/query-language/count.md** - Score: 2 - Marketing language mixed with technical content; convert to technical count function documentation. - -**content/query-language/debug.md** - Score: 2 - Marketing language present; rewrite as technical query debugging documentation. - -**content/query-language/expand-predicates.md** - Score: 2 - Marketing language mixed with technical content; convert to technical expand predicates documentation. - -**content/query-language/facets.md** - Score: 2 - Marketing language mixed with technical content; convert to technical facets documentation. - -**content/query-language/fragments.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL fragments documentation. - -**content/query-language/functions.md** - Score: 2 - Marketing language mixed with technical content; convert to technical query functions reference. - -**content/query-language/graphql-fundamentals.md** - Score: 2 - Marketing language present; rewrite as technical GraphQL fundamentals tutorial. - -**content/query-language/graphql-variables.md** - Score: 2 - Marketing language mixed with technical content; convert to technical GraphQL variables documentation. - -**content/query-language/groupby.md** - Score: 2 - Marketing language present; rewrite as technical groupby function documentation. - -**content/query-language/ignorereflex-directive.md** - Score: 2 - Marketing language mixed with technical content; convert to technical ignorereflex directive documentation. - -**content/query-language/indexing-custom-tokenizers.md** - Score: 2 - Marketing language present; rewrite as technical custom tokenizer documentation. - -**content/query-language/kshortest-path-queries.md** - Score: 2 - Marketing language mixed with technical content; convert to technical shortest path query documentation. - -**content/query-language/language-support.md** - Score: 2 - Marketing language present; rewrite as technical language support documentation. - -**content/query-language/math-on-value-variables.md** - Score: 2 - Marketing language mixed with technical content; convert to technical math operations documentation. - -**content/query-language/multiple-query-blocks.md** - Score: 2 - Marketing language present; rewrite as technical multiple query blocks documentation. - -**content/query-language/normalize-directive.md** - Score: 2 - Marketing language mixed with technical content; convert to technical normalize directive documentation. - -**content/query-language/pagination.md** - Score: 2 - Marketing language present; rewrite as technical pagination documentation. - -**content/query-language/query-variables.md** - Score: 2 - Marketing language mixed with technical content; convert to technical query variables documentation. - -**content/query-language/recurse-query.md** - Score: 2 - Marketing language present; rewrite as technical recursive query documentation. - -**content/query-language/sorting.md** - Score: 2 - Marketing language mixed with technical content; convert to technical sorting documentation. - -**content/query-language/value-variables.md** - Score: 2 - Marketing language present; rewrite as technical value variables documentation. - -**content/ratel/backups.md** - Score: 2 - Marketing language mixed with technical content; convert to technical backup procedures documentation. - -**content/ratel/cluster.md** - Score: 2 - Marketing language present; rewrite as technical cluster management documentation. - -**content/ratel/connection.md** - Score: 2 - Marketing language mixed with technical content; convert to technical connection configuration documentation. - -**content/ratel/console.md** - Score: 2 - Marketing language present; rewrite as technical console usage documentation. - -**content/ratel/overview.md** - Score: 2 - Marketing language mixed with technical content; convert to technical Ratel UI overview documentation. - -**content/ratel/schema.md** - Score: 2 - Marketing language present; rewrite as technical schema management documentation. - -**content/dgraph-glossary.md** - Score: 2 - Marketing language mixed with technical content; convert to technical glossary with precise definitions and examples. - -### Score 3 (Good Documentation with Minor Issues) - -**content/deploy/installation/kubernetes/single-server-cluster.md** - Score: 3 - Good technical content but needs more detailed configuration examples and troubleshooting section. - -**content/deploy/installation/kubernetes/ha-cluster.md** - Score: 3 - Solid technical documentation but could benefit from more production configuration examples and monitoring setup. - -**content/deploy/installation/kubernetes/monitoring-cluster.md** - Score: 3 - Good monitoring setup guide but needs more detailed metrics configuration and alerting examples. - -**content/deploy/installation/kubernetes/cluster-types.md** - Score: 3 - Clear technical documentation but needs more detailed comparison tables and performance characteristics. - -**content/deploy/installation/kubernetes/_index.md** - Score: 3 - Good overview but needs more detailed prerequisites and system requirements section. - -**content/deploy/installation/download.md** - Score: 3 - Clear download instructions but needs more detailed installation verification steps and troubleshooting. - -**content/deploy/installation/lambda-server.md** - Score: 3 - Good technical content but needs more detailed configuration examples and performance tuning guidelines. - -**content/deploy/installation/production-checklist.md** - Score: 3 - Comprehensive checklist but needs more detailed explanations for each item and configuration examples. - -**content/deploy/installation/single-host-setup.md** - Score: 3 - Good setup guide but needs more detailed configuration options and troubleshooting section. - -**content/deploy/admin/data-compression.md** - Score: 3 - Clear technical documentation but needs more detailed performance impact analysis and configuration examples. - -**content/deploy/admin/dgraph-administration.md** - Score: 3 - Good administration guide but needs more detailed command examples and troubleshooting procedures. - -**content/deploy/admin/log-format.md** - Score: 3 - Clear log format documentation but needs more detailed log analysis examples and troubleshooting guides. - -**content/deploy/admin/metrics.md** - Score: 3 - Good metrics documentation but needs more detailed monitoring setup and alerting configuration examples. - -**content/deploy/admin/tracing.md** - Score: 3 - Clear tracing documentation but needs more detailed trace analysis examples and performance impact guidelines. - -**content/deploy/cli-command-reference.md** - Score: 3 - Comprehensive command reference but needs more detailed examples and use cases for each command. - -**content/deploy/cluster-checklist.md** - Score: 3 - Good checklist but needs more detailed explanations and configuration examples for each item. - -**content/deploy/cluster-setup.md** - Score: 3 - Clear setup guide but needs more detailed configuration examples and troubleshooting procedures. - -**content/deploy/config.md** - Score: 3 - Comprehensive configuration reference but needs more detailed examples and best practices for each option. - -**content/deploy/decrypt.md** - Score: 3 - Clear decryption documentation but needs more detailed usage examples and troubleshooting procedures. - -**content/deploy/dgraph-alpha.md** - Score: 3 - Good Alpha server documentation but needs more detailed configuration examples and performance tuning guidelines. - -**content/deploy/dgraph-architecture.md** - Score: 3 - Clear architecture documentation but needs more detailed component interaction diagrams and performance characteristics. - -**content/deploy/dgraph-zero.md** - Score: 3 - Good Zero server documentation but needs more detailed configuration examples and cluster management procedures. - -**content/deploy/monitoring.md** - Score: 3 - Good monitoring guide but needs more detailed setup examples and alerting configuration procedures. - -**content/deploy/security/ports-usage.md** - Score: 3 - Clear port documentation but needs more detailed security considerations and firewall configuration examples. - -**content/deploy/security/tls-configuration.md** - Score: 3 - Good TLS documentation but needs more detailed certificate management procedures and troubleshooting guides. - -**content/deploy/troubleshooting.md** - Score: 3 - Good troubleshooting guide but needs more detailed diagnostic procedures and common issue solutions. - -**content/dql/dql-get-started.md** - Score: 3 - Good quick start guide but needs more detailed examples and common use case scenarios. - -**content/dql/dql-schema.md** - Score: 3 - Clear schema documentation but needs more detailed examples and best practices for schema design. - -**content/dql/dql-syntax/dql-mutation.md** - Score: 3 - Good mutation syntax documentation but needs more detailed examples and error handling procedures. - -**content/dql/dql-syntax/dql-query.md** - Score: 3 - Clear query syntax documentation but needs more detailed examples and performance optimization guidelines. - -**content/dql/dql-syntax/dql-rdf.md** - Score: 3 - Good RDF format documentation but needs more detailed examples and format comparison tables. - -**content/dql/dql-syntax/json-mutation-format.md** - Score: 3 - Clear JSON format documentation but needs more detailed examples and validation procedures. - -**content/dql/predicate-indexing.md** - Score: 3 - Good indexing documentation but needs more detailed performance impact analysis and optimization guidelines. - -**content/graphql/quick-start/index.md** - Score: 3 - Good quick start guide but needs more detailed examples and common integration scenarios. - -**content/graphql/schema/directives/auth.md** - Score: 3 - Clear auth directive documentation but needs more detailed security examples and best practices. - -**content/graphql/schema/directives/directive-dgraph.md** - Score: 3 - Good @dgraph directive documentation but needs more detailed examples and use case scenarios. - -**content/graphql/schema/directives/directive-withsubscription.md** - Score: 3 - Clear subscription directive documentation but needs more detailed real-time examples and performance considerations. - -**content/graphql/schema/directives/search.md** - Score: 3 - Good search directive documentation but needs more detailed search examples and performance optimization guidelines. - -**content/graphql/schema/types.md** - Score: 3 - Clear types documentation but needs more detailed examples and type system best practices. - -**content/graphql/security/jwt.md** - Score: 3 - Good JWT documentation but needs more detailed implementation examples and security best practices. - -**content/graphql/security/cors.md** - Score: 3 - Clear CORS documentation but needs more detailed configuration examples and security considerations. - -**content/graphql/security/mutations.md** - Score: 3 - Good mutation security documentation but needs more detailed examples and security testing procedures. - -**content/howto/importdata/bulk-loader.md** - Score: 3 - Good bulk loader documentation but needs more detailed performance tuning guidelines and troubleshooting procedures. - -**content/howto/importdata/live-loader.md** - Score: 3 - Clear live loader documentation but needs more detailed configuration examples and monitoring procedures. - -**content/howto/upserts.md** - Score: 3 - Good upsert documentation but needs more detailed examples and conflict resolution procedures. - -**content/howto/update-dgraph-types.md** - Score: 3 - Clear schema update documentation but needs more detailed migration procedures and rollback strategies. - -### Score 4 (Excellent Technical Documentation) - -**content/deploy/security/_index.md** - Score: 4 - Excellent security overview with clear categorization and comprehensive coverage of security topics. - -**content/deploy/admin/_index.md** - Score: 4 - Excellent administration overview with clear organization and comprehensive coverage of admin topics. - -**content/dql/dql-syntax/_index.md** - Score: 4 - Excellent DQL syntax overview with clear organization and comprehensive coverage of syntax elements. - -**content/dql/mutations/_index.md** - Score: 4 - Excellent mutations overview with clear organization and comprehensive coverage of mutation operations. - -**content/dql/clients/_index.md** - Score: 4 - Excellent client overview with clear organization and comprehensive coverage of client libraries. - -**content/dql/tips/index.md** - Score: 4 - Excellent tips and best practices guide with practical examples and clear explanations. - -**content/graphql/custom/_index.md** - Score: 4 - Excellent custom resolver overview with clear organization and comprehensive coverage of custom functionality. - -**content/graphql/lambda/_index.md** - Score: 4 - Excellent Lambda resolver overview with clear organization and comprehensive coverage of Lambda functionality. - -**content/graphql/mutations/_index.md** - Score: 4 - Excellent mutations overview with clear organization and comprehensive coverage of mutation operations. - -**content/graphql/queries/_index.md** - Score: 4 - Excellent queries overview with clear organization and comprehensive coverage of query operations. - -**content/graphql/schema/_index.md** - Score: 4 - Excellent schema overview with clear organization and comprehensive coverage of schema elements. - -**content/graphql/schema/directives/_index.md** - Score: 4 - Excellent directives overview with clear organization and comprehensive coverage of directive functionality. - -**content/graphql/security/_index.md** - Score: 4 - Excellent security overview with clear organization and comprehensive coverage of security topics. - -**content/graphql/graphql-clients/_index.md** - Score: 4 - Excellent GraphQL client overview with clear organization and comprehensive coverage of client functionality. - -**content/graphql/graphql-clients/endpoint/_index.md** - Score: 4 - Excellent endpoint overview with clear organization and comprehensive coverage of endpoint functionality. - -**content/graphql/federation/index.md** - Score: 4 - Excellent federation documentation with clear implementation guide and comprehensive coverage of federation features. - -**content/graphql/subscriptions/index.md** - Score: 4 - Excellent subscriptions documentation with clear implementation guide and comprehensive coverage of subscription features. - -**content/howto/_index.md** - Score: 4 - Excellent how-to overview with clear organization and comprehensive coverage of procedural topics. - -**content/howto/commandline/_index.md** - Score: 4 - Excellent CLI overview with clear organization and comprehensive coverage of command-line tools. - -**content/howto/exportdata/_index.md** - Score: 4 - Excellent export overview with clear organization and comprehensive coverage of export procedures. - -**content/howto/importdata/_index.md** - Score: 4 - Excellent import overview with clear organization and comprehensive coverage of import procedures. - -**content/learn/administrator/_index.md** - Score: 4 - Excellent administrator learning path with clear organization and comprehensive coverage of admin topics. - -**content/learn/data-engineer/_index.md** - Score: 4 - Excellent data engineer learning path with clear organization and comprehensive coverage of data engineering topics. - -**content/learn/developer/_index.md** - Score: 4 - Excellent developer learning path with clear organization and comprehensive coverage of development topics. - -**content/migration/_index.md** - Score: 4 - Excellent migration overview with clear organization and comprehensive coverage of migration procedures. - -**content/ratel/_index.md** - Score: 4 - Excellent Ratel UI overview with clear organization and comprehensive coverage of UI functionality. - ---- - -## Summary - -- **Total Pages**: 279 -- **Score 1**: 7 pages (2.5%) - Need major improvement -- **Score 2**: 200 pages (71.7%) - Need significant improvement -- **Score 3**: 25 pages (9.0%) - Good with minor issues -- **Score 4**: 47 pages (16.8%) - Excellent technical documentation - -## Key Issues Identified - -1. **Marketing Language**: Most pages contain marketing language that should be replaced with technical documentation -2. **Missing Examples**: Many pages lack sufficient code examples and practical demonstrations -3. **Incomplete Instructions**: Step-by-step procedures often lack detail and troubleshooting information -4. **Cloud Service References**: Many pages reference cloud services instead of focusing on self-hosted documentation -5. **Lack of Technical Depth**: Pages often provide high-level overviews without technical implementation details - -## Recommendations - -1. **Priority 1**: Focus on Score 1 pages first - these need complete rewrites -2. **Priority 2**: Address Score 2 pages - remove marketing language and add technical depth -3. **Priority 3**: Enhance Score 3 pages with additional examples and troubleshooting -4. **Priority 4**: Use Score 4 pages as templates for improving other pages diff --git a/content/dql/clients/_index.md b/content/clients/_index.md similarity index 96% rename from content/dql/clients/_index.md rename to content/clients/_index.md index a1376fac..0abd594c 100644 --- a/content/dql/clients/_index.md +++ b/content/clients/_index.md @@ -7,7 +7,6 @@ aliases = ["/clients"] type = "docs" [menu.main] identifier = "clients" - parent = "dql" +++ Dgraph client libraries allow you to run DQL transactions, queries and mutations in various programming languages. @@ -55,7 +54,7 @@ transactions conflict when both transactions: - write values to the same scalar predicate of the same node (e.g both attempting to set a particular node's `address` predicate); or - write to a singular `uid` predicate of the same node (changes to `[uid]` predicates can be concurrently written); or -- write a value that conflicts on an index for a predicate with `@upsert` set in the schema (see [upserts]({{< relref "howto/upserts.md">}})). +- write a value that conflicts on an index for a predicate with `@upsert` set in the schema (see [upserts]({{< relref "upserts.md">}})). When a transaction is aborted, all its changes are discarded. Transactions can be manually aborted. diff --git a/content/dql/clients/csharp.md b/content/clients/csharp.md similarity index 100% rename from content/dql/clients/csharp.md rename to content/clients/csharp.md diff --git a/content/dql/clients/go.md b/content/clients/go.md similarity index 100% rename from content/dql/clients/go.md rename to content/clients/go.md diff --git a/content/dql/clients/java.md b/content/clients/java.md similarity index 100% rename from content/dql/clients/java.md rename to content/clients/java.md diff --git a/content/dql/clients/javascript/_index.md b/content/clients/javascript/_index.md similarity index 100% rename from content/dql/clients/javascript/_index.md rename to content/clients/javascript/_index.md diff --git a/content/dql/clients/javascript/grpc.md b/content/clients/javascript/grpc.md similarity index 100% rename from content/dql/clients/javascript/grpc.md rename to content/clients/javascript/grpc.md diff --git a/content/dql/clients/javascript/http.md b/content/clients/javascript/http.md similarity index 100% rename from content/dql/clients/javascript/http.md rename to content/clients/javascript/http.md diff --git a/content/dql/clients/python.md b/content/clients/python.md similarity index 100% rename from content/dql/clients/python.md rename to content/clients/python.md diff --git a/content/dql/clients/raw-http.md b/content/clients/raw-http.md similarity index 99% rename from content/dql/clients/raw-http.md rename to content/clients/raw-http.md index 0be9e1cd..22b63bf3 100644 --- a/content/dql/clients/raw-http.md +++ b/content/clients/raw-http.md @@ -442,7 +442,7 @@ $ curl -X POST --compressed -H "Content-Type: application/dql" localhost:8080/qu ## Run a query in JSON format -The HTTP API also accepts requests in JSON format. For queries you have the keys "query" and "variables". The JSON format is required to set [GraphQL Variables]({{< relref "query-language/graphql-variables.md" >}}) with the HTTP API. +The HTTP API also accepts requests in JSON format. For queries you have the keys "query" and "variables". The JSON format is required to set [GraphQL Variables]({{< relref "graphql-variables.md" >}}) with the HTTP API. This query: diff --git a/content/dql/clients/unofficial-clients.md b/content/clients/unofficial-clients.md similarity index 100% rename from content/dql/clients/unofficial-clients.md rename to content/clients/unofficial-clients.md diff --git a/content/design-concepts/_index.md b/content/design-concepts/_index.md index 222a63b3..8fcd9143 100644 --- a/content/design-concepts/_index.md +++ b/content/design-concepts/_index.md @@ -1,8 +1,8 @@ +++ date = "2017-03-20T22:25:17+11:00" title = "Design Concepts" -weight = 12 type = "docs" +weight = 17 [menu.main] identifier = "design-concepts" +++ diff --git a/content/dgraph-glossary.md b/content/dgraph-glossary.md index c556cb52..8f924923 100644 --- a/content/dgraph-glossary.md +++ b/content/dgraph-glossary.md @@ -3,7 +3,7 @@ title = "Dgraph Glossary" description = "Dgraph terms" type = "docs" [menu.main] - name = "Dgraph Glossary" + name = "Glossary" identifier = "glossary" weight = 16 +++ diff --git a/content/dql/_index.md b/content/dql/_index.md index 2a0c5371..4f37a18d 100644 --- a/content/dql/_index.md +++ b/content/dql/_index.md @@ -1,9 +1,9 @@ +++ -title = "Dgraph Query Language" +title = "Query Language" description = "Dgraph Query Language (DQL) is Dgraph's proprietary language to add, modify, delete and fetch data." type = "docs" [menu.main] - name = "Dgraph Query Language" + name = "Query Language" identifier = "dql" weight = 4 +++ diff --git a/content/dql/dql-syntax/dql-mutation.md b/content/dql/dql-mutation.md similarity index 97% rename from content/dql/dql-syntax/dql-mutation.md rename to content/dql/dql-mutation.md index f555fcc8..0238fe10 100644 --- a/content/dql/dql-syntax/dql-mutation.md +++ b/content/dql/dql-mutation.md @@ -1,11 +1,11 @@ +++ -title = "DQL mutation" +title = "Mutation" type = "docs" [menu.main] - name = "DQL mutation" + name = "Mutation" identifier = "dql-mutation" - parent = "dql-syntax" - weight = 2 + parent = "dql" + weight = 6 +++ Dgraph Query Language (DQL) is Dgraph's proprietary language to add, modify, delete and fetch data. @@ -203,7 +203,7 @@ Execution of an upsert block also returns the response of the query executed on of the database *before mutation was executed*. To get the latest result, you have to execute another query after the transaction is committed. -Variables defined in the query block can be used in the mutation blocks using the [uid]({{< relref "uid-upsert.md" >}}) and [val]({{< relref "val-upsert.md" >}}) functions. +Variables defined in the query block can be used in the mutation blocks using the [uid]({{< relref "upserts.md#val-function" >}}) and [val]({{< relref "upserts.md#val-function" >}}) functions. ## conditional upsert The upsert block also allows specifying conditional mutation blocks using an `@if` diff --git a/content/dql/dql-syntax/dql-rdf.md b/content/dql/dql-rdf.md similarity index 96% rename from content/dql/dql-syntax/dql-rdf.md rename to content/dql/dql-rdf.md index 36e75348..59ee5d2f 100644 --- a/content/dql/dql-syntax/dql-rdf.md +++ b/content/dql/dql-rdf.md @@ -1,11 +1,11 @@ +++ -title = "RDF" +title = "RDF Data Format" type = "docs" [menu.main] name = "RDF" identifier = "dql-rdf" - parent = "dql-syntax" - weight = 3 + parent = "dql" + weight = 2 +++ Dgrpah natively supports Resource Description Framework (RDF) when creating, importing and exporting data. Dgraph Client libraries can be used to query RDF as well. @@ -130,7 +130,7 @@ While most RDF data uses only triples (with three parts) an optional fourth part ## Processing RDF to comply with Dgraph syntax for subjects -While it is valid RDF to specify subjects that are IRI strings, Dgraph requires a numeric UID or a blank node as the subject. If a string IRI is required, Dgraph support them via [xid properties]({{< relref "external-ids-upsert-block" >}}). When importing RDF from another source that does not use numeric UID subjects, it will be required to replace arbitrary subject IRIs with blank node IRIs. +While it is valid RDF to specify subjects that are IRI strings, Dgraph requires a numeric UID or a blank node as the subject. If a string IRI is required, Dgraph support them via [xid properties]({{< relref "upserts.md#external-ids" >}}). When importing RDF from another source that does not use numeric UID subjects, it will be required to replace arbitrary subject IRIs with blank node IRIs. Typically this is done simply by prepending "_:" to the start of the original IRI. So a triple such as: diff --git a/content/dql/dql-schema.md b/content/dql/dql-schema.md index 326586d5..8824e8cb 100644 --- a/content/dql/dql-schema.md +++ b/content/dql/dql-schema.md @@ -1,6 +1,6 @@ +++ date = "2017-03-20T22:25:17+11:00" -title = "Dgraph types schema" +title = "Schema" type = "docs" weight = 3 aliases = ["/dql/type-system","dql/predicate-types"] diff --git a/content/dql/dql-syntax/_index.md b/content/dql/dql-syntax/_index.md deleted file mode 100644 index 2233f242..00000000 --- a/content/dql/dql-syntax/_index.md +++ /dev/null @@ -1,13 +0,0 @@ -+++ -title = "DQL syntax" -weight = 2 -type = "docs" -[menu.main] - name = "DQL Syntax" - identifier = "dql-syntax" - parent = "dql" -+++ - -Dgraph Query Language (DQL) is Dgraph’s proprietary language to add, modify, delete and fetch data. - -Fetching data is done through [DQL Queries]({{< relref "dql-query.md" >}}). Adding, modifying or deleting data is done through [DQL Mutations]({{< relref "dql-mutation.md" >}}). diff --git a/content/dql/dql-syntax/to-sort.md.txt b/content/dql/dql-syntax/to-sort.md.txt deleted file mode 100644 index 93226ecf..00000000 --- a/content/dql/dql-syntax/to-sort.md.txt +++ /dev/null @@ -1,631 +0,0 @@ - -TO DO ---> what if a non mandatory parameter is not provided and used in the query ! ---> what if a parameter is declared but never used in the query - -TO-DO : which notation should be used to describe the grammar (BNF ?) -* `query title($name: string!, @age: int = "95") { ... }` - -Example of query using Variables : - -{{< runnable vars="{\"$a\": \"5\", \"$b\": \"10\", \"$name\": \"Steven Spielberg\"}" >}} -query test($a: int, $b: int, $name: string) { - me(func: allofterms(name@en, $name)) { - name@en - director.film (first: $a, offset: $b) { - name @en - genre(first: $a) { - name@en - } - } - } -} -{{< /runnable >}} - -Example of variables used in an arrays - -{{< runnable vars="{\"$b\": \"10\", \"$aName\": \"Steven Spielberg\", \"$bName\": \"Quentin Tarantino\"}" >}} -query test($a: int = 2, $b: int!, $aName: string, $bName: string) { - me(func: eq(name@en, [$aName, $bName])) { - director.film (first: $a, offset: $b) { - genre(first: $a) { - name@en - } - } - } -} -{{< /runnable >}} - -## Submitting queries to Dgraph server -< TO DO : explain http and grpc enppoint and client - gives links to client page > -### Error Codes - -When running a DQL query you might get an error message from the `/query` endpoint. -Here we will be focusing on the error `"code"` returned in the JSON error object. - -You can usually get two types of error codes: -- [`ErrorInvalidRequest`](#errorinvalidrequest): this error can be either a bad request (`400`) or an internal server error (`500`). -- [`Error`](#error): this is an internal server error (`500`) - -For example, if you submit a query with a syntax error, you'll get: - -```json -{ - "errors": [ - { - "message": "while lexing {\nq(func: has(\"test)){\nuid\n}\n} at line 2 column 12: Unexpected end of input.", - "extensions": { - "code": "ErrorInvalidRequest" - } - } - ], - "data": null -} -``` -The error `"code"` value is returned with the query response. -In this case, it's a syntax error and the error `code` is `ErrorInvalidRequest`. - -##### `Error` - -This is a rare code to get and it's always an internal server error (`500`). -This can happen when JSON marsharling is failing (it's returned when the system tries to marshal a Go struct to JSON) - -##### `ErrorInvalidRequest` - -This is the most common error code that you can get from the `/query` endpoint. This error can be either a bad request (`400`) or an internal server error (`500`). - -For example, you can get this error: -- If the query parameter is not being parsed correctly. The query parameter could be: - - `debug` - - `timeout` - - `startTs` - - `be` (best effort) - - `ro` (read-only) - - If the value of these query parameters is incorrect you would get this error code. This is basically a bad request (`400`) -- If the header's `Content-Type` value is not parsed correctly. The only allowed content types in the header are: - - `application/json` - - `application/dql` - - `application/graphql+-` (deprecated) - - Anything else will be wrongly parsed and end up in a bad request (`400`) -- Query timeout (deadline exceeded). This is an internal server error (`500`) -- Any error in query processing like: - - syntax error - bad request (`400`) - - health failing (server not healthy) - internal server error (`500`) - - Alpha not able to reach zero because of network issue - internal server error (`500`) - - ACL error (user not found or user does not have privileges) - unauthenticated/unauthorized request (`401` or `403`) - - if you set `be=true` and `ro=false` - bad request (`400`) - - any error related to JSON formatting the response - internal server error (`500`) - - -## Submitting queries to Dgraph -### Grpc -### HTTP Raw - - - - -For **HTTP requests** with parameters, we must use `Content-Type: application/json` header and pass data with a JSON object containing `query` and `variables`. - -```sh -curl -H "Content-Type: application/json" localhost:8080/query -XPOST -d $'{ - "query": "query test($a: string) { test(func: eq(name, $a)) { \n uid \n name \n } }", - "variables": { "$a": "Alice" } -}' | python -m json.tool | less -``` - -{{< runnable vars="{\"$a\": \"5\", \"$b\": \"10\", \"$name\": \"Steven Spielberg\"}" >}} -query test($a: int, $b: int, $name: string) { - me(func: allofterms(name@en, $name)) { - name@en - director.film (first: $a, offset: $b) { - name @en - genre(first: $a) { - name@en - } - } - } -} -{{< /runnable >}} - - -* Any variable that is being used must be declared in the named query clause in the beginning. - -{{< runnable vars="{\"$b\": \"10\", \"$name\": \"Steven Spielberg\"}" >}} -query test($a: int = 2, $b: int!, $name: string) { - me(func: allofterms(name@en, $name)) { - director.film (first: $a, offset: $b) { - genre(first: $a) { - name@en - } - } - } -} -{{< /runnable >}} -### Clients - - - -### conditional upsert -## Example of Conditional Upsert - -Let's say in our previous example, we know the `company1` has less than 100 employees. -For safety, we want the mutation to execute only when the variable `v` stores less than -100 but greater than 50 UIDs in it. This can be achieved as follows: - -```sh -curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $' -upsert { - query { - v as var(func: regexp(email, /.*@company1.io$/)) - } - - mutation @if(lt(len(v), 100) AND gt(len(v), 50)) { - delete { - uid(v) * . - uid(v) * . - uid(v) * . - } - } -}' | jq -``` - -We can achieve the same result using `json` dataset as follows: - -```sh -curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d '{ - "query": "{ v as var(func: regexp(email, /.*@company1.io$/)) }", - "cond": "@if(lt(len(v), 100) AND gt(len(v), 50))", - "delete": { - "uid": "uid(v)", - "name": null, - "email": null, - "age": null - } -}' | jq -``` - -## Example of Multiple Mutation Blocks - -Consider an example with the following schema: - -```sh -curl localhost:8080/alter -X POST -d $' - name: string @index(term) . - email: [string] @index(exact) @upsert .' | jq -``` - -Let's say, we have many users stored in our database each having one or more than -one email Addresses. Now, we get two email Addresses that belong to the same user. -If the email Addresses belong to the different nodes in the database, we want to delete -the existing nodes and create a new node with both the emails attached to this new node. -Otherwise, we create/update the new/existing node with both the emails. - -```sh -curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $' -upsert { - query { - # filter is needed to ensure that we do not get same UIDs in u1 and u2 - q1(func: eq(email, "user_email1@company1.io")) @filter(not(eq(email, "user_email2@company1.io"))) { - u1 as uid - } - - q2(func: eq(email, "user_email2@company1.io")) @filter(not(eq(email, "user_email1@company1.io"))) { - u2 as uid - } - - q3(func: eq(email, "user_email1@company1.io")) @filter(eq(email, "user_email2@company1.io")) { - u3 as uid - } - } - - # case when both emails do not exist - mutation @if(eq(len(u1), 0) AND eq(len(u2), 0) AND eq(len(u3), 0)) { - set { - _:user "user" . - _:user "Person" . - _:user "user_email1@company1.io" . - _:user "user_email2@company1.io" . - } - } - - # case when email1 exists but email2 does not - mutation @if(eq(len(u1), 1) AND eq(len(u2), 0) AND eq(len(u3), 0)) { - set { - uid(u1) "user_email2@company1.io" . - } - } - - # case when email1 does not exist but email2 exists - mutation @if(eq(len(u1), 0) AND eq(len(u2), 1) AND eq(len(u3), 0)) { - set { - uid(u2) "user_email1@company1.io" . - } - } - - # case when both emails exist and needs merging - mutation @if(eq(len(u1), 1) AND eq(len(u2), 1) AND eq(len(u3), 0)) { - set { - _:user "user" . - _:user "Person" . - _:user "user_email1@company1.io" . - _:user "user_email2@company1.io" . - } - - delete { - uid(u1) * . - uid(u1) * . - uid(u2) * . - uid(u2) * . - } - } -}' | jq -``` - -Result (when database is empty): - -```json -{ - "data": { - "q1": [], - "q2": [], - "q3": [], - "code": "Success", - "message": "Done", - "uids": { - "user": "0x1" - } - }, - "extensions": {...} -} -``` - -Result (both emails exist and are attached to different nodes): -```json -{ - "data": { - "q1": [ - { - "uid": "0x2" - } - ], - "q2": [ - { - "uid": "0x3" - } - ], - "q3": [], - "code": "Success", - "message": "Done", - "uids": { - "user": "0x4" - } - }, - "extensions": {...} -} -``` - -Result (when both emails exist and are already attached to the same node): - -```json -{ - "data": { - "q1": [], - "q2": [], - "q3": [ - { - "uid": "0x4" - } - ], - "code": "Success", - "message": "Done", - "uids": {} - }, - "extensions": {...} -} -``` - -We can achieve the same result using `json` dataset as follows: - -```sh -curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d '{ - "query": "{q1(func: eq(email, \"user_email1@company1.io\")) @filter(not(eq(email, \"user_email2@company1.io\"))) {u1 as uid} \n q2(func: eq(email, \"user_email2@company1.io\")) @filter(not(eq(email, \"user_email1@company1.io\"))) {u2 as uid} \n q3(func: eq(email, \"user_email1@company1.io\")) @filter(eq(email, \"user_email2@company1.io\")) {u3 as uid}}", - "mutations": [ - { - "cond": "@if(eq(len(u1), 0) AND eq(len(u2), 0) AND eq(len(u3), 0))", - "set": [ - { - "uid": "_:user", - "name": "user", - "dgraph.type": "Person" - }, - { - "uid": "_:user", - "email": "user_email1@company1.io", - "dgraph.type": "Person" - }, - { - "uid": "_:user", - "email": "user_email2@company1.io", - "dgraph.type": "Person" - } - ] - }, - { - "cond": "@if(eq(len(u1), 1) AND eq(len(u2), 0) AND eq(len(u3), 0))", - "set": [ - { - "uid": "uid(u1)", - "email": "user_email2@company1.io", - "dgraph.type": "Person" - } - ] - }, - { - "cond": "@if(eq(len(u1), 1) AND eq(len(u2), 0) AND eq(len(u3), 0))", - "set": [ - { - "uid": "uid(u2)", - "email": "user_email1@company1.io", - "dgraph.type": "Person" - } - ] - }, - { - "cond": "@if(eq(len(u1), 1) AND eq(len(u2), 1) AND eq(len(u3), 0))", - "set": [ - { - "uid": "_:user", - "name": "user", - "dgraph.type": "Person" - }, - { - "uid": "_:user", - "email": "user_email1@company1.io", - "dgraph.type": "Person" - }, - { - "uid": "_:user", - "email": "user_email2@company1.io", - "dgraph.type": "Person" - } - ], - "delete": [ - { - "uid": "uid(u1)", - "name": null, - "email": null - }, - { - "uid": "uid(u2)", - "name": null, - "email": null - } - ] - } - ] -}' | jq -``` - -## reverse edge ?? -Any outgoing edge in Dgraph can be reversed using the `@reverse` directive in the schema and be queried using tilde as the prefix of the edge name. e.g. `<~myEdge>`. - -Dgraph serializes directed graphs. This means that all properties always point from an entity to another entity or value in a single direction. `S P -> O`. - -Reverse edges are automatically generated edges and are not part of your dataset. This means that you cannot run mutations directly on the reverse edges. Mutating the forward edge will automatically update the reverse edge. - -**Using Reverse Edges correctly** - -In RDF the arrangement of the triples already defines what can be reversed. - -```RDF -_:MyObject _:BlankNode . #That's the right syntax of a reverse edge. -_:BlankNode "Person" . -``` - -The easiest way to correct and apply reverse edges is using JSON. It is simply having the directive on schema at the desired edge. When building your mutations remember that there is no reverse syntax in JSON. So what you should do is similar to RDF: change the arrangement of the JSON objects. - -Since `MyObject` is above the `Person` entity, `MyObject` must come before when formatting the mutation. - -```JSON -{ - "set": [ - { - "uid": "_:MyObject", - "dgraph.type": "Object", - "myEdge": { - "uid": "_:BlankNode", - "dgraph.type": "Person" - } - } - ] -} -``` - -Another way to do this is to separate into small chunks/batches and use blank nodes as references. This facilitates the organization and reuse of references. - -```JSON -{ - "set": [ - { - "uid": "_:MyObject", - "dgraph.type": "Object", - "myEdge": [{"uid": "_:BlankNode"}] - }, - { - "uid": "_:BlankNode", - "dgraph.type": "Person" - } - ] -} -``` - -### More reverse examples - -In RDF the correct way to apply reverse edges is very straight-forward. - -```RDF -name: String . -husband: uid @reverse . -wife: uid @reverse . -parent: [uid] @reverse . -``` - -```RDF -{ - set { - _:Megalosaurus "Earl Sneed Sinclair" . - _:Megalosaurus "Dinosaur" . - _:Megalosaurus _:Allosaurus . - _:Allosaurus "Francis Johanna Phillips Sinclair" (short="Fran") . - _:Allosaurus "Dinosaur" . - _:Allosaurus _:Megalosaurus . - _:Hypsilophodon "Robert Mark Sinclair" (short="Robbie") . - _:Hypsilophodon "Dinosaur" . - _:Hypsilophodon _:Allosaurus (role="son") . - _:Hypsilophodon _:Megalosaurus (role="son") . - _:Protoceratops "Charlene Fiona Sinclair" . - _:Protoceratops "Dinosaur" . - _:Protoceratops _:Allosaurus (role="daughter") . - _:Protoceratops _:Megalosaurus (role="daughter") . - _:MegalosaurusBaby "Baby Sinclair" (short="Baby") . - _:MegalosaurusBaby "Dinosaur" . - _:MegalosaurusBaby _:Allosaurus (role="son") . - _:MegalosaurusBaby _:Megalosaurus (role="son") . - } -} -``` - -The directions are like: - -```rdf -Exchanged hierarchy: - Object -> Parent; - Object <~ Parent; #Reverse - Children to parents via "parent" edge. - wife and husband bidirectional using reverse. -Normal hierarchy: - Parent -> Object; - Parent <~ Object; #Reverse - This hierarchy is not part of the example, but is generally used in all graph models. - To make this hierarchy we need to bring the hierarchical relationship starting from the parents and not from the children. Instead of using the edges "wife" and "husband" we switch to single edge called "married" to simplify the model. - _:Megalosaurus "Earl Sneed Sinclair" . - _:Megalosaurus "Dinosaur" . - _:Megalosaurus _:Allosaurus . - _:Megalosaurus _:Hypsilophodon (role="son") . - _:Megalosaurus _:Protoceratops (role="daughter") . - _:Megalosaurus _:MegalosaurusBaby (role="son") . - _:Allosaurus "Francis Johanna Phillips Sinclair" (short="Fran") . - _:Allosaurus "Dinosaur" . - _:Allosaurus _:Megalosaurus . - _:Allosaurus _:Hypsilophodon (role="son") . - _:Allosaurus _:Protoceratops (role="daughter") . - _:Allosaurus _:MegalosaurusBaby (role="son") . -``` - -### Queries - -1. `wife_husband` is the reversed `wife` edge. -2. `husband` is an actual edge. - -```graphql -{ - q(func: has(wife)) { - name - WF as wife { - name - } - } - reverseIt(func: uid(WF)) { - name - wife_husband : ~wife { - name - } - husband { - name - } - } -} -``` - -1. `Children` is the reversed `parent` edge. - -```graphql -{ - q(func: has(name)) @filter(eq(name, "Earl Sneed Sinclair")){ - name - Children : ~parent @facets { - name - } - } -} -``` - -### Reverse Edges and Facets - -Facets on reverse edges are the same as the forward edge. That is, if you set or update a facet on an edge, its reverse will have the same facets. - -```rdf -{ - set { - _:Megalosaurus "Earl Sneed Sinclair" . - _:Megalosaurus "Dinosaur" . - _:Megalosaurus _:Allosaurus . - _:Megalosaurus _:MegalosaurusBaby (role="parent -> child") . - _:MegalosaurusBaby "Baby Sinclair" (short="Baby -> parent") . - _:MegalosaurusBaby "Dinosaur" . - _:MegalosaurusBaby _:Megalosaurus (role="child -> parent") . - } -} -``` - -Using a similar query from the previous example: - -```graphql -{ - Parent(func: has(name)) @filter(eq(name, "Earl Sneed Sinclair")){ - name - C as Children : parent @facets { - name - } - } - Child(func: uid(C)) { - name - parent @facets { - name - } - } -} -``` - -```json -{ - "data": { - "Parent": [ - { - "name": "Earl Sneed Sinclair", - "Children": [ - { - "name": "Baby Sinclair", - "Children|role": "parent -> child" - } - ] - } - ], - "Child": [ - { - "name": "Baby Sinclair", - "parent": [ - { - "name": "Earl Sneed Sinclair", - "parent|role": "child -> parent" - } - ] - } - ] - } -} - ``` -## bulk delete to put in drop data - -Drop data in admin ? -Individual triples, patterns of triples and predicates can be deleted as described in the [DQL docs]({{< relref "mutations/delete.md" >}}). diff --git a/content/dql/dql-syntax/json-mutation-format.md b/content/dql/json-mutation-format.md similarity index 99% rename from content/dql/dql-syntax/json-mutation-format.md rename to content/dql/json-mutation-format.md index b2727f30..3b601abd 100644 --- a/content/dql/dql-syntax/json-mutation-format.md +++ b/content/dql/json-mutation-format.md @@ -1,11 +1,10 @@ +++ date = "2023-02-23T22:25:17+11:00" -title = "JSON Mutation Format" -weight = 10 +title = "JSON Data Format" type = "docs" [menu.main] - parent = "dql-syntax" - weight = 4 + parent = "dql" + weight = 1 +++ Dgraph supports [Mutations]({{< relref "dql-mutation.md" >}}) in JSON or [RDF]({{< relref "dql-rdf.md" >}}) format. When using JSON format Dgraph creates nodes and relationships from the JSON structure and assigns UIDs to nodes. diff --git a/content/dql/mutations/_index.md b/content/dql/mutations/_index.md deleted file mode 100644 index 970e2779..00000000 --- a/content/dql/mutations/_index.md +++ /dev/null @@ -1,11 +0,0 @@ -+++ -date = "2017-03-20T19:35:35+11:00" -title = "Mutations" -weight = 6 -type = "docs" -[menu.main] - identifier = "mutations" - parent = "dql" -+++ - -Adding or removing data in Dgraph is called a mutation. \ No newline at end of file diff --git a/content/dql/mutations/external-ids-upsert-block.md b/content/dql/mutations/external-ids-upsert-block.md deleted file mode 100644 index 3dd25daf..00000000 --- a/content/dql/mutations/external-ids-upsert-block.md +++ /dev/null @@ -1,87 +0,0 @@ -+++ -date = "2017-03-20T22:25:17+11:00" -title = "External IDs and Upsert Block" -type = "docs" -weight = 4 -[menu.main] - parent = "mutations" -+++ - -The upsert block makes managing external IDs easy. - -Set the schema. -``` -xid: string @index(exact) . -: string @index(exact) . -: [uid] @reverse . -``` - -Set the type first of all. -``` -{ - set { - _:blank "http://schema.org/Person" . - _:blank "ExternalType" . - } -} -``` - -Now you can create a new person and attach its type using the upsert block. -``` - upsert { - query { - var(func: eq(xid, "http://schema.org/Person")) { - Type as uid - } - var(func: eq(, "Robin Wright")) { - Person as uid - } - } - mutation { - set { - uid(Person) "https://www.themoviedb.org/person/32-robin-wright" . - uid(Person) uid(Type) . - uid(Person) "Robin Wright" . - uid(Person) "Person" . - } - } - } -``` - -You can also delete a person and detach the relation between Type and Person Node. It's the same as above, but you use the keyword "delete" instead of "set". "`http://schema.org/Person`" will remain but "`Robin Wright`" will be deleted. - -``` - upsert { - query { - var(func: eq(xid, "http://schema.org/Person")) { - Type as uid - } - var(func: eq(, "Robin Wright")) { - Person as uid - } - } - mutation { - delete { - uid(Person) "https://www.themoviedb.org/person/32-robin-wright" . - uid(Person) uid(Type) . - uid(Person) "Robin Wright" . - uid(Person) "Person" . - } - } - } -``` - -Query by user. -``` -{ - q(func: eq(, "Robin Wright")) { - uid - xid - - { - uid - xid - } - } -} -``` \ No newline at end of file diff --git a/content/dql/mutations/uid-upsert.md b/content/dql/mutations/uid-upsert.md deleted file mode 100644 index 928e66a1..00000000 --- a/content/dql/mutations/uid-upsert.md +++ /dev/null @@ -1,210 +0,0 @@ -+++ -date = "2017-03-20T22:25:17+11:00" -title = "uid function in upsert" -type = "docs" -weight = 1 -[menu.main] - parent = "mutations" -+++ - -The upsert block contains one query block and mutation blocks. Variables defined -in the query block can be used in the mutation blocks using the `uid` and `val` function. - -The `uid` function allows extracting UIDs from variables defined in the query block. -There are two possible outcomes based on the results of executing the query block: - -* If the variable is empty i.e. no node matched the query, the `uid` function returns a new UID in case of a `set` operation and is thus treated similar to a blank node. On the other hand, for `delete/del` operation, it returns no UID, and thus the operation becomes a no-op and is silently ignored. A blank node gets the same UID across all the mutation blocks. -* If the variable stores one or more than one UIDs, the `uid` function returns all the UIDs stored in the variable. In this case, the operation is performed on all the UIDs returned, one at a time. - - -## Example of `uid` Function - -Consider an example with the following schema: - -```sh -curl localhost:8080/alter -X POST -d $' - name: string @index(term) . - email: string @index(exact, trigram) @upsert . - age: int @index(int) .' | jq -``` - -Now, let's say we want to create a new user with `email` and `name` information. -We also want to make sure that one email has exactly one corresponding user in -the database. To achieve this, we need to first query whether a user exists -in the database with the given email. If a user exists, we use its UID -to update the `name` information. If the user doesn't exist, we create -a new user and update the `email` and `name` information. - -We can do this using the upsert block as follows: - -```sh -curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $' -upsert { - query { - q(func: eq(email, "user@company1.io")) { - v as uid - name - } - } - - mutation { - set { - uid(v) "first last" . - uid(v) "user@company1.io" . - } - } -}' | jq -``` - -Result: - -```json -{ - "data": { - "q": [], - "code": "Success", - "message": "Done", - "uids": { - "uid(v)": "0x1" - } - }, - "extensions": {...} -} -``` - -The query part of the upsert block stores the UID of the user with the provided email -in the variable `v`. The mutation part then extracts the UID from variable `v`, and -stores the `name` and `email` information in the database. If the user exists, -the information is updated. If the user doesn't exist, `uid(v)` is treated -as a blank node and a new user is created as explained above. - -If we run the same mutation again, the data would just be overwritten, and no new uid is -created. Note that the `uids` map is empty in the result when the mutation is executed -again and the `data` map (key `q`) contains the uid that was created in the previous upsert. - -```json -{ - "data": { - "q": [ - { - "uid": "0x1", - "name": "first last" - } - ], - "code": "Success", - "message": "Done", - "uids": {} - }, - "extensions": {...} -} -``` - -We can achieve the same result using `json` dataset as follows: - -```sh -curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d ' -{ - "query": "{ q(func: eq(email, \"user@company1.io\")) {v as uid, name} }", - "set": { - "uid": "uid(v)", - "name": "first last", - "email": "user@company1.io" - } -}' | jq -``` - -Now, we want to add the `age` information for the same user having the same email -`user@company1.io`. We can use the upsert block to do the same as follows: - -```sh -curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $' -upsert { - query { - q(func: eq(email, "user@company1.io")) { - v as uid - } - } - - mutation { - set { - uid(v) "28" . - } - } -}' | jq -``` - -Result: - -```json -{ - "data": { - "q": [ - { - "uid": "0x1" - } - ], - "code": "Success", - "message": "Done", - "uids": {} - }, - "extensions": {...} -} -``` - -Here, the query block queries for a user with `email` as `user@company1.io`. It stores -the `uid` of the user in variable `v`. The mutation block then updates the `age` of the -user by extracting the uid from the variable `v` using `uid` function. - -We can achieve the same result using `json` dataset as follows: - -```sh -curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d $' -{ - "query": "{ q(func: eq(email, \\"user@company1.io\\")) {v as uid} }", - "set":{ - "uid": "uid(v)", - "age": "28" - } -}' | jq -``` - -If we want to execute the mutation only when the user exists, we could use -[Conditional Upsert]({{< relref "dql-mutation.md#conditional-upsert" >}}). - - - -## Bulk Delete Example - -Let's say we want to delete all the users of `company1` from the database. This can be -achieved in just one query using the upsert block as follows: - -```sh -curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $' -upsert { - query { - v as var(func: regexp(email, /.*@company1.io$/)) - } - - mutation { - delete { - uid(v) * . - uid(v) * . - uid(v) * . - } - } -}' | jq -``` - -We can achieve the same result using `json` dataset as follows: - -```sh -curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d '{ - "query": "{ v as var(func: regexp(email, /.*@company1.io$/)) }", - "delete": { - "uid": "uid(v)", - "name": null, - "email": null, - "age": null - } -}' | jq -``` diff --git a/content/dql/mutations/val-upsert.md b/content/dql/mutations/val-upsert.md deleted file mode 100644 index 907565cb..00000000 --- a/content/dql/mutations/val-upsert.md +++ /dev/null @@ -1,82 +0,0 @@ -+++ -date = "2017-03-20T22:25:17+11:00" -title = "val function in upsert" -type = "docs" -weight = 2 -[menu.main] - parent = "mutations" -+++ - -The upsert block allows performing queries and mutations in a single request. The upsert -block contains one query block and one or more than one mutation blocks. Variables defined -in the query block can be used in the mutation blocks using the `uid` and `val` function. - - -The `val` function allows extracting values from value variables. Value variables store -a mapping from UIDs to their corresponding values. Hence, `val(v)` is replaced by the value -stored in the mapping for the UID (Subject) in the N-Quad. If the variable `v` has no value -for a given UID, the mutation is silently ignored. The `val` function can be used with the -result of aggregate variables as well, in which case, all the UIDs in the mutation would -be updated with the aggregate value. - - -## Example of `val` Function - -Let's say we want to migrate the predicate `age` to `other`. We can do this using the -following mutation: - -```sh -curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $' -upsert { - query { - v as var(func: has(age)) { - a as age - } - } - - mutation { - # we copy the values from the old predicate - set { - uid(v) val(a) . - } - - # and we delete the old predicate - delete { - uid(v) * . - } - } -}' | jq -``` - -Result: - -```json -{ - "data": { - "code": "Success", - "message": "Done", - "uids": {} - }, - "extensions": {...} -} -``` - -Here, variable `a` will store a mapping from all the UIDs to their `age`. The mutation -block then stores the corresponding value of `age` for each UID in the `other` predicate -and deletes the `age` predicate. - -We can achieve the same result using `json` dataset as follows: - -```sh -curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d $'{ - "query": "{ v as var(func: regexp(email, /.*@company1.io$/)) }", - "delete": { - "uid": "uid(v)", - "age": null - }, - "set": { - "uid": "uid(v)", - "other": "val(a)" - } -}' | jq -``` diff --git a/content/dql/predicate-indexing.md b/content/dql/predicate-indexing.md index 4bf3a896..5e14373f 100644 --- a/content/dql/predicate-indexing.md +++ b/content/dql/predicate-indexing.md @@ -1,6 +1,6 @@ +++ date = "2017-03-20T22:25:17+11:00" -title = "Predicate indexes" +title = "Indexes" type = "docs" weight = 4 [menu.main] diff --git a/content/dql/query/_index.md b/content/dql/query/_index.md new file mode 100644 index 00000000..746fb0d8 --- /dev/null +++ b/content/dql/query/_index.md @@ -0,0 +1,15 @@ ++++ +title = "Query" +type = "docs" +[menu.main] + name = "Query" + identifier = "query-language" + parent = "dql" + weight = 5 ++++ + +Dgraph Query Language (DQL) is Dgraph’s proprietary language to add, modify, delete and fetch data. + +Fetching data is done through [Queries]({{< relref "dql-query.md" >}}). + +Adding, modifying or deleting data is done through [Mutations]({{< relref "dql-mutation.md" >}}). diff --git a/content/query-language/aggregation.md b/content/dql/query/aggregation.md similarity index 97% rename from content/query-language/aggregation.md rename to content/dql/query/aggregation.md index 145ffc3d..c858c88b 100644 --- a/content/query-language/aggregation.md +++ b/content/dql/query/aggregation.md @@ -23,7 +23,7 @@ Schema Types: | `min` / `max` | `int`, `float`, `string`, `dateTime`, `default` | | `sum` / `avg` | `int`, `float` | -Aggregation can only be applied to [value variables]({{< relref "query-language/value-variables.md">}}). An index is not required (the values have already been found and stored in the value variable mapping). +Aggregation can only be applied to [value variables]({{< relref "value-variables.md">}}). An index is not required (the values have already been found and stored in the value variable mapping). An aggregation is applied at the query block enclosing the variable definition. As opposed to query variables and value variables, which are global, aggregation is computed locally. For example: ``` diff --git a/content/query-language/alias.md b/content/dql/query/alias.md similarity index 100% rename from content/query-language/alias.md rename to content/dql/query/alias.md diff --git a/content/query-language/connecting-filters.md b/content/dql/query/connecting-filters.md similarity index 100% rename from content/query-language/connecting-filters.md rename to content/dql/query/connecting-filters.md diff --git a/content/query-language/count.md b/content/dql/query/count.md similarity index 88% rename from content/query-language/count.md rename to content/dql/query/count.md index 0042cf83..189d1a89 100644 --- a/content/query-language/count.md +++ b/content/dql/query/count.md @@ -27,7 +27,7 @@ Query Example: The number of films acted in by each actor with `Orlando` in thei } {{< /runnable >}} -Count can be used at root and [aliased]({{< relref "query-language/alias.md" >}}). +Count can be used at root and [aliased]({{< relref "alias.md" >}}). Query Example: Count of directors who have directed more than five films. When used at the query root, the [count index]({{< relref "dql-schema.md#count-index" >}}) is required. @@ -40,7 +40,7 @@ Query Example: Count of directors who have directed more than five films. When {{< /runnable >}} -Count can be assigned to a [value variable]({{< relref "query-language/value-variables.md">}}). +Count can be assigned to a [value variable]({{< relref "value-variables.md">}}). Query Example: The actors of Ang Lee's "Eat Drink Man Woman" ordered by the number of movies acted in. diff --git a/content/query-language/debug.md b/content/dql/query/debug.md similarity index 100% rename from content/query-language/debug.md rename to content/dql/query/debug.md diff --git a/content/dql/query/directive/_index.md b/content/dql/query/directive/_index.md new file mode 100644 index 00000000..951d3c58 --- /dev/null +++ b/content/dql/query/directive/_index.md @@ -0,0 +1,33 @@ ++++ +title = "Directives" +type = "docs" +[menu.main] + name = "Directives" + identifier = "dql-directives" + parent = "query-language" + weight = 16 ++++ + +Directives in Dgraph Query Language (DQL) are special annotations that modify how queries are executed or how results are formatted. They are prefixed with the `@` symbol and can be applied to query blocks or predicates to change their behavior. + +Directives provide powerful control over: + +- **Response structure**: Format and organize query results +- **Graph traversal**: Control how the graph is explored +- **Pattern matching**: Filter results based on complete query structure +- **Aggregation**: Group and aggregate data + +## Available Directives + +- **[@normalize]({{< relref "normalize-directive.md" >}})**: Flattens the response structure by removing nesting and returning only aliased predicates. + +- **[@cascade]({{< relref "cascade-directive.md" >}})**: Filters out nodes that don't match all predicates specified in the query at any nested level, enabling pattern matching behavior. + +- **[@recurse]({{< relref "recurse-query.md" >}})**: Performs recursive graph traversal, following relationships to explore paths of variable depth. + +- **[@ignorereflex]({{< relref "ignorereflex-directive.md" >}})**: Ignores reflexive edges (edges that point back to the same node) during graph traversal. + +- **[@groupby]({{< relref "groupby.md" >}})**: Groups query results based on specified predicates and allows aggregation functions to be applied to each group. + +Directives can be combined in a single query to achieve complex querying and result formatting requirements. + diff --git a/content/query-language/cascade-directive.md b/content/dql/query/directive/cascade-directive.md similarity index 99% rename from content/query-language/cascade-directive.md rename to content/dql/query/directive/cascade-directive.md index 1baa0c54..262b22a7 100644 --- a/content/query-language/cascade-directive.md +++ b/content/dql/query/directive/cascade-directive.md @@ -1,10 +1,10 @@ +++ date = "2017-03-20T22:25:17+11:00" -title = "Cascade Directive" +title = "@cascade" type = "docs" -weight = 15 +weight = 1 [menu.main] - parent = "query-language" + parent = "dql-directives" +++ With the `@cascade` directive, nodes that don't have all predicates specified in the query are removed. This can be useful in cases where some filter was applied or if nodes might not have all listed predicates. diff --git a/content/query-language/groupby.md b/content/dql/query/directive/groupby.md similarity index 97% rename from content/query-language/groupby.md rename to content/dql/query/directive/groupby.md index 5d3737c1..88345345 100644 --- a/content/query-language/groupby.md +++ b/content/dql/query/directive/groupby.md @@ -1,10 +1,10 @@ +++ date = "2017-03-20T22:25:17+11:00" -title = "GroupBy" +title = "@groupby" type = "docs" -weight = 13 +weight = 2 [menu.main] - parent = "query-language" + parent = "dql-directives" +++ Syntax Examples: diff --git a/content/query-language/ignorereflex-directive.md b/content/dql/query/directive/ignorereflex-directive.md similarity index 88% rename from content/query-language/ignorereflex-directive.md rename to content/dql/query/directive/ignorereflex-directive.md index e3c9c1a2..dae32603 100644 --- a/content/query-language/ignorereflex-directive.md +++ b/content/dql/query/directive/ignorereflex-directive.md @@ -1,10 +1,10 @@ +++ date = "2017-03-20T22:25:17+11:00" -title = "@ignorereflex Directive" +title = "@ignorereflex" type = "docs" -weight = 18 +weight = 3 [menu.main] - parent = "query-language" + parent = "dql-directives" +++ The `@ignorereflex` directive forces the removal of child nodes that are reachable from themselves as a parent, through any path in the query result diff --git a/content/query-language/normalize-directive.md b/content/dql/query/directive/normalize-directive.md similarity index 95% rename from content/query-language/normalize-directive.md rename to content/dql/query/directive/normalize-directive.md index 0b0ee15d..fc6aac9b 100644 --- a/content/query-language/normalize-directive.md +++ b/content/dql/query/directive/normalize-directive.md @@ -1,10 +1,10 @@ +++ date = "2017-03-20T22:25:17+11:00" -title = "@normalize Directive" +title = "@normalize" type = "docs" -weight = 17 +weight = 4 [menu.main] - parent = "query-language" + parent = "dql-directives" +++ With the `@normalize` directive, only aliased predicates are returned and the result is flattened to remove nesting. diff --git a/content/query-language/recurse-query.md b/content/dql/query/directive/recurse-query.md similarity index 95% rename from content/query-language/recurse-query.md rename to content/dql/query/directive/recurse-query.md index 97feb699..5ca06323 100644 --- a/content/query-language/recurse-query.md +++ b/content/dql/query/directive/recurse-query.md @@ -1,10 +1,10 @@ +++ date = "2017-03-20T22:25:17+11:00" -title = "Recurse Query" +title = "@recurse" type = "docs" -weight = 24 +weight = 5 [menu.main] - parent = "query-language" + parent = "dql-directives" +++ `Recurse` queries let you traverse a set of predicates (with filter, facets, etc.) until we reach all leaf nodes or we reach the maximum depth which is specified by the `depth` parameter. diff --git a/content/dql/dql-syntax/dql-query.md b/content/dql/query/dql-query.md similarity index 81% rename from content/dql/dql-syntax/dql-query.md rename to content/dql/query/dql-query.md index d70c9a7b..278b9c7f 100644 --- a/content/dql/dql-syntax/dql-query.md +++ b/content/dql/query/dql-query.md @@ -1,11 +1,11 @@ +++ -title = "DQL query" +title = "Query Structure" type = "docs" +weight = 2 [menu.main] - name = "DQL query" + name = "Query Structure" identifier = "dql-query" - parent = "dql-syntax" - weight = 1 + parent = "query-language" +++ Fetching data with Dgraph Query Language (DQL), is done through **DQL Queries**. Adding, modifying or deleting data is done through [DQL Mutations]({{< relref "dql-mutation.md" >}}). @@ -34,7 +34,7 @@ A DQL query has * may have a default value. In the example below, `$age` has a default value of `95` * may be mandatory by suffixing the type with a `!`. Mandatory parameters can't have a default value. -Variables can be used in the query where a string, float, int or bool value are needed. +Parameters can be used in the query where a string, float, int or bool value are needed. You can also use a variable holding ``uids`` by using a string variable and by providing the value as a quoted list in square brackets: `query title($uidsParam: string = "[0x1, 0x2, 0x3]") { ... }`. @@ -53,7 +53,7 @@ The query parameterization is optional. If you don't use parameters you can omit {{
}} {{% notice "note" %}}The current documentation is usually using example of queries without parameters. {{% /notice %}} -If you execute this query in our [Movies demo database]({{< relref "graphql-fundamentals.md" >}}) you can see that Dgraph will return a JSON structure similar to the request : +If you execute this query in our [Movies demo database]({{< relref "running-examples.md" >}}) you can see that Dgraph will return a JSON structure similar to the request : {{
}} ### Query block @@ -73,8 +73,8 @@ For each relationships to fetch, the query is using a nested block. A nested block - may specify filters to apply on the related nodes -- may specify criteria on the relationships attributes using [filtering on facets]({{< relref "query-language/facets.md#filtering-on-facets" >}})) -- provides the list of relationship attributes ([facets]({{< relref "query-language/facets.md" >}}))) to fetch. +- may specify criteria on the relationships attributes using [filtering on facets]({{< relref "facets.md#filtering-on-facets" >}})) +- provides the list of relationship attributes ([facets]({{< relref "facets.md" >}}))) to fetch. - provides the list of attributes and relationships to fetch for the related nodes. A nested block may contain another nested block, and such at any level. @@ -89,9 +89,9 @@ A nested block may contain another nested block, and such at any level. ### Formatting options Dgraph returns the attributes and relationships that you specified in the query. You can specify an alternate name for the result by using [aliases]({{< relref "alias.md" >}}). -You can flatten the response structure at any level using [@normalize]({{< relref "query-language/normalize-directive.md" >}}) directive. +You can flatten the response structure at any level using [@normalize]({{< relref "normalize-directive.md" >}}) directive. -Entering the list of all the attributes you want to fetch could be fastidious for large queries or repeating blocks : you may take advantage of [fragments]({{< relref "query-language/fragments.md" >}}) and the [expand function]({{< relref "query-language/expand-predicates.md" >}}). +Entering the list of all the attributes you want to fetch could be fastidious for large queries or repeating blocks : you may take advantage of [fragments]({{< relref "fragments.md" >}}) and the [expand function]({{< relref "expand-predicates.md" >}}). ### Node criteria (used by root function or by filter) @@ -134,11 +134,11 @@ Dgraph offers functions for ### Summarizing functions -When dealing with array attributes or with relationships to many node, the query may use summary functions [count]({{< relref "query-language/count.md" >}}) , [min]({{< relref "query-language/aggregation.md#min" >}}), [max]({{< relref "query-language/aggregation.md#max" >}}), [avg]({{< relref "query-language/aggregation.md#sum-and-avg" >}}) or [sum]({{< relref "query-language/aggregation.md#sum-and-avg" >}}). +When dealing with array attributes or with relationships to many node, the query may use summary functions [count]({{< relref "count.md" >}}) , [min]({{< relref "aggregation.md#min" >}}), [max]({{< relref "aggregation.md#max" >}}), [avg]({{< relref "aggregation.md#sum-and-avg" >}}) or [sum]({{< relref "aggregation.md#sum-and-avg" >}}). -The query may also contain [mathematical functions]({{< relref "query-language/math-on-value-variables.md" >}}) on value variables. +The query may also contain [mathematical functions]({{< relref "math-on-value-variables.md" >}}) on value variables. -Summary functions can be used in conjunction with [@grouby]({{< relref "query-language/groupby.md" >}}) directive to create aggregated value variables. +Summary functions can be used in conjunction with [@grouby]({{< relref "groupby.md" >}}) directive to create aggregated value variables. The query may contain **anonymous block** to return computed values. **Anonymous block** don't have a root criteria as they are not used to search for nodes but only to returned computed values. @@ -146,13 +146,13 @@ The query may contain **anonymous block** to return computed values. **Anonymous When you specify nested blocks and filters you basically describe a way to traverse the graph. -[@recurse]({{< relref "query-language/recurse-query.md" >}}) and [@ignorereflex]({{< relref "query-language/ignorereflex-directive.md" >}}) are directives used to optionally configure the graph traversal. +[@recurse]({{< relref "recurse-query.md" >}}) and [@ignorereflex]({{< relref "ignorereflex-directive.md" >}}) are directives used to optionally configure the graph traversal. ### Pattern matching -Queries with nested blocks with filters may be turned into pattern matching using [@cascade]({{< relref "query-language/cascade-directive.md" >}}) directive : nodes that don’t have all attributes and all relationships specified in the query at any sub level are not considered in the result. So only nodes "matching" the complete query structure are returned. +Queries with nested blocks with filters may be turned into pattern matching using [@cascade]({{< relref "cascade-directive.md" >}}) directive : nodes that don’t have all attributes and all relationships specified in the query at any sub level are not considered in the result. So only nodes "matching" the complete query structure are returned. ### Graph algorithms -The query can ask for the shortest path between a source (from) node and destination (to) node using the [shortest]({{< relref "query-language/kshortest-path-queries.md" >}}) query block. +The query can ask for the shortest path between a source (from) node and destination (to) node using the [shortest]({{< relref "kshortest-path-queries.md" >}}) query block. ### Comments Anything on a line following a `#` is a comment diff --git a/content/query-language/expand-predicates.md b/content/dql/query/expand-predicates.md similarity index 95% rename from content/query-language/expand-predicates.md rename to content/dql/query/expand-predicates.md index b0facdce..8f58f60f 100644 --- a/content/query-language/expand-predicates.md +++ b/content/dql/query/expand-predicates.md @@ -67,7 +67,7 @@ veterinarian {{% notice "note" %}} For `string` predicates, `expand` only returns values not tagged with a language -(see [language preference]({{< relref "query-language/graphql-fundamentals.md#language-support" >}})). So it's often +(see [language preference]({{< relref "graphql-fundamentals.md#language-support" >}})). So it's often required to add `name@fr` or `name@.` as well to an expand query. {{% /notice %}} diff --git a/content/query-language/facets.md b/content/dql/query/facets.md similarity index 97% rename from content/query-language/facets.md rename to content/dql/query/facets.md index 5c5aa585..8b138f26 100644 --- a/content/query-language/facets.md +++ b/content/dql/query/facets.md @@ -289,7 +289,7 @@ Charlie by their `rating` which is a facet. ## Assigning Facet values to a variable -Facets on UID edges can be stored in [value variables]({{< relref "query-language/value-variables.md" >}}). The variable is a map from the edge target to the facet value. +Facets on UID edges can be stored in [value variables]({{< relref "value-variables.md" >}}). The variable is a map from the edge target to the facet value. Alice's friends reported by variables for `close` and `relative`. {{< runnable >}} @@ -313,7 +313,7 @@ Alice's friends reported by variables for `close` and `relative`. ## Facets and Variable Propagation -Facet values of `int` and `float` can be assigned to variables and thus the [values propagate]({{< relref "query-language/value-variables.md#variable-propagation" >}}). +Facet values of `int` and `float` can be assigned to variables and thus the [values propagate]({{< relref "value-variables.md#variable-propagation" >}}). Alice, Bob and Charlie each rated every movie. A value variable on facet `rating` maps movies to ratings. A query that reaches a movie through multiple paths sums the ratings on each path. The following sums Alice, Bob and Charlie's ratings for the three movies. diff --git a/content/query-language/fragments.md b/content/dql/query/fragments.md similarity index 100% rename from content/query-language/fragments.md rename to content/dql/query/fragments.md diff --git a/content/query-language/functions.md b/content/dql/query/functions.md similarity index 98% rename from content/query-language/functions.md rename to content/dql/query/functions.md index 12cbc363..69394711 100644 --- a/content/query-language/functions.md +++ b/content/dql/query/functions.md @@ -7,14 +7,14 @@ weight = 2 parent = "query-language" +++ -Functions allow filtering based on properties of nodes or [variables]({{}}). Functions can be applied in the query root or in filters. +Functions allow filtering based on properties of nodes or [variables]({{}}). Functions can be applied in the query root or in filters. {{% notice "note" %}}Support for filters on non-indexed predicates was added with Dgraph `v1.2.0`. {{% /notice %}} Comparison functions (`eq`, `ge`, `gt`, `le`, `lt`) in the query root (aka `func:`) can only be applied on [indexed predicates]({{< relref "dql-schema.md#indexing" >}}). Since v1.2, comparison functions -can now be used on [@filter]({{}}) directives even on predicates +can now be used on [@filter]({{}}) directives even on predicates that have not been indexed. Filtering on non-indexed predicates can be slow for large datasets, as they require iterating over all of the possible values at the level where the filter is being used. @@ -77,7 +77,7 @@ Index Required: `term` Matches strings that have any of the specified terms in any order; case insensitive. #### Usage at root -Query Example: All nodes that have a `name` containing either `poison` or `peacock`. Many of the returned nodes are movies, but people like Joan Peacock also meet the search terms because without a [cascade directive]({{< relref "query-language/cascade-directive.md">}}) the query doesn't require a genre. +Query Example: All nodes that have a `name` containing either `poison` or `peacock`. Many of the returned nodes are movies, but people like Joan Peacock also meet the search terms because without a [cascade directive]({{< relref "cascade-directive.md">}}) the query doesn't require a genre. {{< runnable >}} { diff --git a/content/query-language/graphql-variables.md b/content/dql/query/graphql-variables.md similarity index 92% rename from content/query-language/graphql-variables.md rename to content/dql/query/graphql-variables.md index 2e15a83c..c3aa7236 100644 --- a/content/query-language/graphql-variables.md +++ b/content/dql/query/graphql-variables.md @@ -1,8 +1,8 @@ +++ date = "2017-03-20T22:25:17+11:00" -title = "GraphQL Variables" +title = "Query parameters" type = "docs" -weight = 26 +weight = 3 [menu.main] parent = "query-language" +++ @@ -15,7 +15,7 @@ Syntax Examples (using default values): * `query title($uids: string = "[0x1, 0x2, 0x3]") { ... }`. The value of the variable is a quoted array. `Variables` can be defined and used in queries which helps in query reuse and avoids costly string building in clients at runtime by passing a separate variable map. A variable starts with a `$` symbol. -For **HTTP requests** with GraphQL Variables, we must use `Content-Type: application/json` header and pass data with a JSON object containing `query` and `variables`. +For **HTTP requests** with Query parameters, we must use `Content-Type: application/json` header and pass data with a JSON object containing `query` and `variables`. ```sh curl -H "Content-Type: application/json" localhost:8080/query -XPOST -d $'{ @@ -56,7 +56,7 @@ query test($a: int = 2, $b: int!, $name: string) { } {{< /runnable >}} -You can also use array with GraphQL Variables. +You can also use array with Query parameters. {{< runnable vars="{\"$b\": \"10\", \"$aName\": \"Steven Spielberg\", \"$bName\": \"Quentin Tarantino\"}" >}} query test($a: int = 2, $b: int!, $aName: string, $bName: string) { diff --git a/content/query-language/indexing-custom-tokenizers.md b/content/dql/query/indexing-custom-tokenizers.md similarity index 100% rename from content/query-language/indexing-custom-tokenizers.md rename to content/dql/query/indexing-custom-tokenizers.md diff --git a/content/query-language/kshortest-path-queries.md b/content/dql/query/kshortest-path-queries.md similarity index 99% rename from content/query-language/kshortest-path-queries.md rename to content/dql/query/kshortest-path-queries.md index b29b04e2..975817e0 100644 --- a/content/query-language/kshortest-path-queries.md +++ b/content/dql/query/kshortest-path-queries.md @@ -106,7 +106,7 @@ We can return more paths by specifying `numpaths`. Setting `numpaths: 2` returns } ``` -{{% notice "note" %}}In the query above, instead of using UID literals, we query both people using var blocks and the `uid()` function. You can also combine it with [GraphQL Variables]({{< relref "query-language/graphql-variables.md" >}}).{{% /notice %}} +{{% notice "note" %}}In the query above, instead of using UID literals, we query both people using var blocks and the `uid()` function. You can also combine it with [GraphQL Variables]({{< relref "graphql-variables.md" >}}).{{% /notice %}} ## Edge weight diff --git a/content/query-language/language-support.md b/content/dql/query/language-support.md similarity index 96% rename from content/query-language/language-support.md rename to content/dql/query/language-support.md index 3b70c7fd..d4605ea6 100644 --- a/content/query-language/language-support.md +++ b/content/dql/query/language-support.md @@ -44,7 +44,7 @@ above. --- -In [full-text search functions]({{< relref "query-language/functions.md#full-text-search" >}}) +In [full-text search functions]({{< relref "functions.md#full-text-search" >}}) (`alloftext`, `anyoftext`), when no language is specified (untagged or `@.`), the default (English) full-text tokenizer is used. This does not mean that the value with the `en` tag will be searched when querying the untagged value, diff --git a/content/query-language/math-on-value-variables.md b/content/dql/query/math-on-value-variables.md similarity index 100% rename from content/query-language/math-on-value-variables.md rename to content/dql/query/math-on-value-variables.md diff --git a/content/query-language/multiple-query-blocks.md b/content/dql/query/multiple-query-blocks.md similarity index 100% rename from content/query-language/multiple-query-blocks.md rename to content/dql/query/multiple-query-blocks.md diff --git a/content/query-language/pagination.md b/content/dql/query/pagination.md similarity index 98% rename from content/query-language/pagination.md rename to content/dql/query/pagination.md index a66d0d4f..4221cfd4 100644 --- a/content/query-language/pagination.md +++ b/content/dql/query/pagination.md @@ -9,7 +9,7 @@ weight = 5 Pagination allows returning only a portion, rather than the whole, result set. This can be useful for top-k style queries as well as to reduce the size of the result set for client side processing or to allow paged access to results. -Pagination is often used with [sorting]({{< relref "query-language/sorting.md">}}). +Pagination is often used with [sorting]({{< relref "sorting.md">}}). {{% notice "note" %}}Without a sort order specified, the results are sorted by `uid`, which is assigned randomly. So the ordering, while deterministic, might not be what you expected.{{% /notice %}} ## First diff --git a/content/query-language/query-variables.md b/content/dql/query/query-variables.md similarity index 100% rename from content/query-language/query-variables.md rename to content/dql/query/query-variables.md diff --git a/content/query-language/graphql-fundamentals.md b/content/dql/query/running-examples.md similarity index 100% rename from content/query-language/graphql-fundamentals.md rename to content/dql/query/running-examples.md diff --git a/content/query-language/sorting.md b/content/dql/query/sorting.md similarity index 96% rename from content/query-language/sorting.md rename to content/dql/query/sorting.md index 18e1812f..a01a0d13 100644 --- a/content/query-language/sorting.md +++ b/content/dql/query/sorting.md @@ -26,7 +26,7 @@ Dgraph returns `null` values at the end of the results, irrespective of their so {{% /notice %}} {{% notice "tip" %}} -Sorted queries retrieve up to 1000 results by default. This can be changed with [first]({{< relref "query-language/pagination.md#first">}}). +Sorted queries retrieve up to 1000 results by default. This can be changed with [first]({{< relref "pagination.md#first">}}). {{% /notice %}} diff --git a/content/query-language/value-variables.md b/content/dql/query/value-variables.md similarity index 98% rename from content/query-language/value-variables.md rename to content/dql/query/value-variables.md index 07badfd9..917f68f1 100644 --- a/content/query-language/value-variables.md +++ b/content/dql/query/value-variables.md @@ -25,7 +25,7 @@ It is an error to define a value variable but not use it elsewhere in the query. Value variables are used by extracting the values with `val(var-name)`, or by extracting the UIDs with `uid(var-name)`. -[Facet]({{< relref "query-language/facets.md">}}) values can be stored in value variables. +[Facet]({{< relref "facets.md">}}) values can be stored in value variables. Query Example: The number of movie roles played by the actors of the 80's classic "The Princess Bride". Query variable `pbActors` matches the UIDs of all actors from the movie. Value variable `roles` is thus a map from actor UID to number of roles. Value variable `roles` can be used in the `totalRoles` query block because that query block also matches the `pbActors` UIDs, so the actor to number of roles map is available. diff --git a/content/dql/tips/index.md b/content/dql/tips/index.md index 98cf69df..4d93025a 100644 --- a/content/dql/tips/index.md +++ b/content/dql/tips/index.md @@ -1,7 +1,7 @@ +++ title = "DQL: Tips and Tricks" type = "docs" -weight = 7 +weight = 9 [menu.main] identifier = "tips" parent = "dql" @@ -63,9 +63,9 @@ Use the `has` function among the value variables to search on non-indexed predic ## Sort edge by nested node values -Dgraph [sorting]({{< relref "query-language/sorting.md" >}}) is based on a single +Dgraph [sorting]({{< relref "sorting.md" >}}) is based on a single level of the subgraph. To sort a level by the values of a deeper level, use -[query variables]({{< relref "query-language/query-variables.md" >}}) to bring +[query variables]({{< relref "query-variables.md" >}}) to bring nested values up to the level of the edge to be sorted. Example: Get all actors from a Steven Spielberg movie sorted alphabetically. diff --git a/content/dql/upserts.md b/content/dql/upserts.md new file mode 100644 index 00000000..30fccfbc --- /dev/null +++ b/content/dql/upserts.md @@ -0,0 +1,433 @@ ++++ +date = "2017-03-20T22:25:17+11:00" +title = "Upsert" +type = "docs" + +[menu.main] + parent = "dql" + weight = 7 ++++ + +Upsert-style operations are operations where: + +1. A node is searched for, and then +2. Depending on if it is found or not, either: + - Updating some of its attributes, or + - Creating a new node with those attributes. + +The upsert has to be an atomic operation such that either a new node is +created, or an existing node is modified. It's not allowed that two concurrent +upserts both create a new node. + +There are many examples where upserts are useful. Most examples involve the +creation of a 1 to 1 mapping between two different entities. E.g. associating +email addresses with user accounts. + +Upserts are common in both traditional RDBMSs and newer NoSQL databases. +Dgraph is no exception. + +## Upsert Procedure + +In Dgraph, upsert-style behavior can be implemented by users on top of +transactions. The steps are as follows: + +1. Create a new transaction. + +2. Query for the node. This will usually be as simple as `{ q(func: eq(email, + "bob@example.com")) { uid }}`. If a `uid` result is returned, then that's the +`uid` for the existing node. If no results are returned, then the user account +doesn't exist. + +3. In the case where the user account doesn't exist, then a new node has to be + created. This is done in the usual way by making a mutation (inside the +transaction), e.g. the RDF `_:newAccount "bob@example.com" .`. The +`uid` assigned can be accessed by looking up the blank node name `newAccount` +in the `Assigned` object returned from the mutation. + +4. Now that you have the `uid` of the account (either new or existing), you can + modify the account (using additional mutations) or perform queries on it in +whichever way you wish. + +## Upserts in DQL and GraphQL + +You can also use the `Upsert Block` in DQL to achieve the upsert procedure in a single + mutation. The request will contain both the query and the mutation as explained +[here]({{< relref "dql-mutation.md#Update data with upsert block" >}}). + +In GraphQL, you can use the `upsert` input variable in an `add` mutation, as explained [here]({{< relref "graphql/mutations/upsert.md">}}). + +## Conflicts + +Upsert operations are intended to be run concurrently, as per the needs of the +application. As such, it's possible that two concurrently running operations +could try to add the same node at the same time. For example, both try to add a +user with the same email address. If they do, then one of the transactions will +fail with an error indicating that the transaction was aborted. + +If this happens, the transaction is rolled back and it's up to the user's +application logic to retry the whole operation. The transaction has to be +retried in its entirety, all the way from creating a new transaction. + +The choice of index placed on the predicate is important for performance. +**Hash is almost always the best choice of index for equality checking.** + +{{% notice "note" %}} +It's the _index_ that typically causes upsert conflicts to occur. The index is +stored as many key/value pairs, where each key is a combination of the +predicate name and some function of the predicate value (e.g. its hash for the +hash index). If two transactions modify the same key concurrently, then one +will fail. +{{% /notice %}} + +The upsert block contains one query block and mutation blocks. Variables defined +in the query block can be used in the mutation blocks using the `uid` and `val` function. + +The `uid` function allows extracting UIDs from variables defined in the query block. +There are two possible outcomes based on the results of executing the query block: + +* If the variable is empty i.e. no node matched the query, the `uid` function returns a new UID in case of a `set` operation and is thus treated similar to a blank node. On the other hand, for `delete/del` operation, it returns no UID, and thus the operation becomes a no-op and is silently ignored. A blank node gets the same UID across all the mutation blocks. +* If the variable stores one or more than one UIDs, the `uid` function returns all the UIDs stored in the variable. In this case, the operation is performed on all the UIDs returned, one at a time. + + +## Example of `uid` Function + +Consider an example with the following schema: + +```sh +curl localhost:8080/alter -X POST -d $' + name: string @index(term) . + email: string @index(exact, trigram) @upsert . + age: int @index(int) .' | jq +``` + +Now, let's say we want to create a new user with `email` and `name` information. +We also want to make sure that one email has exactly one corresponding user in +the database. To achieve this, we need to first query whether a user exists +in the database with the given email. If a user exists, we use its UID +to update the `name` information. If the user doesn't exist, we create +a new user and update the `email` and `name` information. + +We can do this using the upsert block as follows: + +```sh +curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $' +upsert { + query { + q(func: eq(email, "user@company1.io")) { + v as uid + name + } + } + + mutation { + set { + uid(v) "first last" . + uid(v) "user@company1.io" . + } + } +}' | jq +``` + +Result: + +```json +{ + "data": { + "q": [], + "code": "Success", + "message": "Done", + "uids": { + "uid(v)": "0x1" + } + }, + "extensions": {...} +} +``` + +The query part of the upsert block stores the UID of the user with the provided email +in the variable `v`. The mutation part then extracts the UID from variable `v`, and +stores the `name` and `email` information in the database. If the user exists, +the information is updated. If the user doesn't exist, `uid(v)` is treated +as a blank node and a new user is created as explained above. + +If we run the same mutation again, the data would just be overwritten, and no new uid is +created. Note that the `uids` map is empty in the result when the mutation is executed +again and the `data` map (key `q`) contains the uid that was created in the previous upsert. + +```json +{ + "data": { + "q": [ + { + "uid": "0x1", + "name": "first last" + } + ], + "code": "Success", + "message": "Done", + "uids": {} + }, + "extensions": {...} +} +``` + +We can achieve the same result using `json` dataset as follows: + +```sh +curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d ' +{ + "query": "{ q(func: eq(email, \"user@company1.io\")) {v as uid, name} }", + "set": { + "uid": "uid(v)", + "name": "first last", + "email": "user@company1.io" + } +}' | jq +``` + +Now, we want to add the `age` information for the same user having the same email +`user@company1.io`. We can use the upsert block to do the same as follows: + +```sh +curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $' +upsert { + query { + q(func: eq(email, "user@company1.io")) { + v as uid + } + } + + mutation { + set { + uid(v) "28" . + } + } +}' | jq +``` + +Result: + +```json +{ + "data": { + "q": [ + { + "uid": "0x1" + } + ], + "code": "Success", + "message": "Done", + "uids": {} + }, + "extensions": {...} +} +``` + +Here, the query block queries for a user with `email` as `user@company1.io`. It stores +the `uid` of the user in variable `v`. The mutation block then updates the `age` of the +user by extracting the uid from the variable `v` using `uid` function. + +We can achieve the same result using `json` dataset as follows: + +```sh +curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d $' +{ + "query": "{ q(func: eq(email, \\"user@company1.io\\")) {v as uid} }", + "set":{ + "uid": "uid(v)", + "age": "28" + } +}' | jq +``` + +If we want to execute the mutation only when the user exists, we could use +[Conditional Upsert]({{< relref "dql-mutation.md#conditional-upsert" >}}). + + + +## Bulk Delete Example + +Let's say we want to delete all the users of `company1` from the database. This can be +achieved in just one query using the upsert block as follows: + +```sh +curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $' +upsert { + query { + v as var(func: regexp(email, /.*@company1.io$/)) + } + + mutation { + delete { + uid(v) * . + uid(v) * . + uid(v) * . + } + } +}' | jq +``` + +We can achieve the same result using `json` dataset as follows: + +```sh +curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d '{ + "query": "{ v as var(func: regexp(email, /.*@company1.io$/)) }", + "delete": { + "uid": "uid(v)", + "name": null, + "email": null, + "age": null + } +}' | jq +``` +## val function +Variables defined in the query block can be used in the mutation blocks using the `uid` and `val` function. + + +The `val` function allows extracting values from value variables. Value variables store +a mapping from UIDs to their corresponding values. Hence, `val(v)` is replaced by the value +stored in the mapping for the UID (Subject) in the N-Quad. If the variable `v` has no value +for a given UID, the mutation is silently ignored. The `val` function can be used with the +result of aggregate variables as well, in which case, all the UIDs in the mutation would +be updated with the aggregate value. + + +### Example of `val` Function + +Let's say we want to migrate the predicate `age` to `other`. We can do this using the +following mutation: + +```sh +curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $' +upsert { + query { + v as var(func: has(age)) { + a as age + } + } + + mutation { + # we copy the values from the old predicate + set { + uid(v) val(a) . + } + + # and we delete the old predicate + delete { + uid(v) * . + } + } +}' | jq +``` + +Result: + +```json +{ + "data": { + "code": "Success", + "message": "Done", + "uids": {} + }, + "extensions": {...} +} +``` + +Here, variable `a` will store a mapping from all the UIDs to their `age`. The mutation +block then stores the corresponding value of `age` for each UID in the `other` predicate +and deletes the `age` predicate. + +We can achieve the same result using `json` dataset as follows: + +```sh +curl -H "Content-Type: application/json" -X POST localhost:8080/mutate?commitNow=true -d $'{ + "query": "{ v as var(func: regexp(email, /.*@company1.io$/)) }", + "delete": { + "uid": "uid(v)", + "age": null + }, + "set": { + "uid": "uid(v)", + "other": "val(a)" + } +}' | jq +``` +## External ids +The upsert block makes managing external IDs easy. + +Set the schema. +``` +xid: string @index(exact) . +: string @index(exact) . +: [uid] @reverse . +``` + +Set the type first of all. +``` +{ + set { + _:blank "http://schema.org/Person" . + _:blank "ExternalType" . + } +} +``` + +Now you can create a new person and attach its type using the upsert block. +``` + upsert { + query { + var(func: eq(xid, "http://schema.org/Person")) { + Type as uid + } + var(func: eq(, "Robin Wright")) { + Person as uid + } + } + mutation { + set { + uid(Person) "https://www.themoviedb.org/person/32-robin-wright" . + uid(Person) uid(Type) . + uid(Person) "Robin Wright" . + uid(Person) "Person" . + } + } + } +``` + +You can also delete a person and detach the relation between Type and Person Node. It's the same as above, but you use the keyword "delete" instead of "set". "`http://schema.org/Person`" will remain but "`Robin Wright`" will be deleted. + +``` + upsert { + query { + var(func: eq(xid, "http://schema.org/Person")) { + Type as uid + } + var(func: eq(, "Robin Wright")) { + Person as uid + } + } + mutation { + delete { + uid(Person) "https://www.themoviedb.org/person/32-robin-wright" . + uid(Person) uid(Type) . + uid(Person) "Robin Wright" . + uid(Person) "Person" . + } + } + } +``` + +Query by user. +``` +{ + q(func: eq(, "Robin Wright")) { + uid + xid + + { + uid + xid + } + } +} +``` \ No newline at end of file diff --git a/content/graphql/schema/directives/_index.md b/content/graphql/schema/directives/_index.md index 5683497f..f88dba7e 100644 --- a/content/graphql/schema/directives/_index.md +++ b/content/graphql/schema/directives/_index.md @@ -82,13 +82,11 @@ Reference: [Lambda directive]({{< relref "lambda-overview.md" >}}) `@remote` directive is used to annotate types for which data is not stored in Dgraph. These types are typically used with custom queries and mutations. -Reference: [Remote directive]({{< relref "directive.md#remote-types" >}}) ### @remoteResponse The `@remoteResponse` directive allows you to annotate the fields of a `@remote` type in order to map a custom query's JSON key response to a GraphQL field. -Reference: [Remote directive]({{< relref "directive.md##remote-response" >}}) ### @search diff --git a/content/howto/dql-schema-request.md b/content/howto/dql-schema-request.md index a0303045..0abd8831 100644 --- a/content/howto/dql-schema-request.md +++ b/content/howto/dql-schema-request.md @@ -10,7 +10,7 @@ weight = 14 You can retrieve the Dgraph schema containing the list of predicates types and node types by: - issuing a query on /query endpoint using the [HTTP Client]({{< relref "raw-http#query-current-dql-schema">}}) -- issuing a query using any [DQL client library]({{< relref "dql/clients">}}) +- issuing a query using any [DQL client library]({{< relref "clients">}}) - using [Ratel UI]({{< relref "ratel/schema">}}) - using the Cloud console through the [DQL Schema](https://cloud.dgraph.io/_/schema?tab=dqlschema) tab of the Schema section. diff --git a/content/howto/update-dgraph-types.md b/content/howto/update-dgraph-types.md index 3fab0fd1..01eda295 100644 --- a/content/howto/update-dgraph-types.md +++ b/content/howto/update-dgraph-types.md @@ -11,7 +11,7 @@ identifier = "update-types" You modify Dgraph types (node types and predicates types) by - issuing a request to the ``/alter`` endpoint using the [HTTP Client]({{< relref "raw-http#alter-the-dql-schema">}}) -- using an ``alter`` operation of any [DQL client library]({{< relref "dql/clients">}}). +- using an ``alter`` operation of any [DQL client library]({{< relref "clients">}}). - using [Ratel UI]({{< relref "ratel/schema">}}) - using the Cloud console through the [DQL Schema](https://cloud.dgraph.io/_/schema?tab=dqlschema) tab of the Schema section. diff --git a/content/howto/upserts.md b/content/howto/upserts.md deleted file mode 100644 index 247286e7..00000000 --- a/content/howto/upserts.md +++ /dev/null @@ -1,79 +0,0 @@ -+++ -date = "2017-03-20T22:25:17+11:00" -title = "Upserts" -type = "docs" -weight = 9 -[menu.main] - parent = "howto" -+++ - -Upsert-style operations are operations where: - -1. A node is searched for, and then -2. Depending on if it is found or not, either: - - Updating some of its attributes, or - - Creating a new node with those attributes. - -The upsert has to be an atomic operation such that either a new node is -created, or an existing node is modified. It's not allowed that two concurrent -upserts both create a new node. - -There are many examples where upserts are useful. Most examples involve the -creation of a 1 to 1 mapping between two different entities. E.g. associating -email addresses with user accounts. - -Upserts are common in both traditional RDBMSs and newer NoSQL databases. -Dgraph is no exception. - -## Upsert Procedure - -In Dgraph, upsert-style behavior can be implemented by users on top of -transactions. The steps are as follows: - -1. Create a new transaction. - -2. Query for the node. This will usually be as simple as `{ q(func: eq(email, - "bob@example.com")) { uid }}`. If a `uid` result is returned, then that's the -`uid` for the existing node. If no results are returned, then the user account -doesn't exist. - -3. In the case where the user account doesn't exist, then a new node has to be - created. This is done in the usual way by making a mutation (inside the -transaction), e.g. the RDF `_:newAccount "bob@example.com" .`. The -`uid` assigned can be accessed by looking up the blank node name `newAccount` -in the `Assigned` object returned from the mutation. - -4. Now that you have the `uid` of the account (either new or existing), you can - modify the account (using additional mutations) or perform queries on it in -whichever way you wish. - -## Upserts in DQL and GraphQL - -You can also use the `Upsert Block` in DQL to achieve the upsert procedure in a single - mutation. The request will contain both the query and the mutation as explained -[here]({{< relref "dql-mutation.md#Update data with upsert block" >}}). - -In GraphQL, you can use the `upsert` input variable in an `add` mutation, as explained [here]({{< relref "graphql/mutations/upsert.md">}}). - -## Conflicts - -Upsert operations are intended to be run concurrently, as per the needs of the -application. As such, it's possible that two concurrently running operations -could try to add the same node at the same time. For example, both try to add a -user with the same email address. If they do, then one of the transactions will -fail with an error indicating that the transaction was aborted. - -If this happens, the transaction is rolled back and it's up to the user's -application logic to retry the whole operation. The transaction has to be -retried in its entirety, all the way from creating a new transaction. - -The choice of index placed on the predicate is important for performance. -**Hash is almost always the best choice of index for equality checking.** - -{{% notice "note" %}} -It's the _index_ that typically causes upsert conflicts to occur. The index is -stored as many key/value pairs, where each key is a combination of the -predicate name and some function of the predicate value (e.g. its hash for the -hash index). If two transactions modify the same key concurrently, then one -will fail. -{{% /notice %}} \ No newline at end of file diff --git a/content/learn/data-engineer/_index.md b/content/learn/data-engineer/_index.md index 083519a8..b0a80792 100644 --- a/content/learn/data-engineer/_index.md +++ b/content/learn/data-engineer/_index.md @@ -17,7 +17,7 @@ weight = 3 - Get familiar with some terms in the [Glossary]({{< relref "dgraph-glossary.md" >}}). - Follow the [Dgraph Query Language(DQL) Quickstart]({{< relref "dql/dql-get-started" >}}) to execute some queries. - Follow the [Get Started with Dgraph]({{< relref "learn/data-engineer/get-started-with-dgraph" >}}) tutorial. -- Use [DQL Syntax]({{< relref "dql/dql-syntax">}}) and [Query Language]({{< relref "query-language/_index.md" >}}) as references. +- Use [DQL Syntax]({{< relref "dql-query.md">}}) and [Query Language]({{< relref "_index.md" >}}) as references. - Go to [Clients]({{< relref "clients" >}}) to see how to communicate with Dgraph from your application. diff --git a/content/learn/data-engineer/get-started-with-dgraph/tutorial-8/index.md b/content/learn/data-engineer/get-started-with-dgraph/tutorial-8/index.md index 3cfec444..16410238 100644 --- a/content/learn/data-engineer/get-started-with-dgraph/tutorial-8/index.md +++ b/content/learn/data-engineer/get-started-with-dgraph/tutorial-8/index.md @@ -11,7 +11,7 @@ type = "learn" In the [previous tutorial]({{< relref "tutorial-7/index.md">}}), we learned about building a twitter-like user-search feature using -[Dgraph's fuzzy search]({{< relref "query-language/functions.md#fuzzy-matching">}}). +[Dgraph's fuzzy search]({{< relref "functions.md#fuzzy-matching">}}). In this tutorial, we'll build a graph of tourist locations around San Francisco and help our Zoologist friend, Mary, and her team in their mission to conserve birds @@ -114,7 +114,7 @@ via the `has_type` edge. _Note: Dgraph allows you to associate one or more types for the nodes using its type system feature, for now, we are using nodes without types, we'll learn about type system for nodes in a future tutorial. Check -[this page from the documentation site](https://dgraph.io/docs/query-language/#type-system), +[this page from the documentation site](https://dgraph.io/docs/#type-system), if you want to explore type system feature for nodes._ Here is our sample dataset. @@ -1540,7 +1540,7 @@ built-in function `near` to find the hotels near the Golden gate bridge. Here is the syntax of the `near` function: `near(geo-predicate, [long, lat], distance)`. -The [`near` function](https://dgraph.io/docs/query-language/#near) matches and +The [`near` function](https://dgraph.io/docs/#near) matches and returns all the geo-predicates stored in the database which are within `distance meters` of geojson coordinate `[long, lat]` provided by the user. @@ -1674,7 +1674,7 @@ our newsletter to get the latest tutorial right into your inbox. - Go to [Clients]({{< relref "clients" >}}) to see how to communicate with Dgraph from your application. -- A wider range of queries can also be found in the [Query Language]({{< relref "query-language/_index.md" >}}) reference. +- A wider range of queries can also be found in the [Query Language]({{< relref "_index.md" >}}) reference. - See [Deploy]({{< relref "deploy/_index.md" >}}) if you wish to run Dgraph in a cluster. diff --git a/content/query-language/_index.md b/content/query-language/_index.md deleted file mode 100644 index 6e29c82d..00000000 --- a/content/query-language/_index.md +++ /dev/null @@ -1,9 +0,0 @@ -+++ -date = "2017-03-20T22:25:17+11:00" -title = "Query Language" -type = "docs" -weight = 6 -[menu.main] - identifier = "query-language" - parent = "dql" -+++ diff --git a/scripts/linkcheck.sh b/scripts/linkcheck.sh deleted file mode 100644 index 2b0de4fd..00000000 --- a/scripts/linkcheck.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -# Script to check for broken links in the Hugo-generated site - -set -e - -GREEN='\033[32;1m' -RED='\033[31;1m' -YELLOW='\033[33;1m' -RESET='\033[0m' - -echo -e "${GREEN}Building Hugo site...${RESET}" -hugo --destination=public --baseURL=http://example.com 1> /dev/null - -echo -e "${GREEN}Checking for broken links...${RESET}" - -# Option 1: htmltest (uses .htmltest.yml config) -if command -v htmltest &> /dev/null; then - echo -e "${YELLOW}Using htmltest...${RESET}" - htmltest -c .htmltest.yml -# Option 2: HTMLProofer (requires Ruby and html-proofer gem) -elif command -v htmlproofer &> /dev/null; then - echo -e "${YELLOW}Using HTMLProofer...${RESET}" - htmlproofer \ - --allow-hash-href \ - --check-html \ - --disable-external \ - --empty-alt-ignore \ - --url-ignore "/#/" \ - ./public -else - echo -e "${RED}HTMLProofer not found.${RESET}" - echo "Install it with: gem install html-proofer" - exit 1 -fi - -echo -e "${GREEN}Link check complete!${RESET}" - From 7b53b15ee5f6ceb1017d0de62c45f71804446069 Mon Sep 17 00:00:00 2001 From: raphael-istari Date: Wed, 29 Oct 2025 20:52:09 -0700 Subject: [PATCH 2/3] re-organize navigation --- content/dql/dql-rdf.md | 1 + .../{query => }/indexing-custom-tokenizers.md | 6 +- content/dql/json-mutation-format.md | 1 + content/dql/query/aggregation.md | 2 +- content/dql/query/connecting-filters.md | 28 -- content/dql/query/count.md | 2 +- content/dql/query/directive/_index.md | 3 + .../dql/query/directive/cascade-directive.md | 2 +- content/dql/query/directive/filter.md | 88 ++++++ content/dql/query/dql-query.md | 156 +++++++++- content/dql/query/expand-predicates.md | 2 +- content/dql/query/facets.md | 4 +- content/dql/query/functions.md | 11 +- content/dql/query/math-on-value-variables.md | 99 ------- content/dql/query/multiple-query-blocks.md | 162 ---------- content/dql/query/query-variables.md | 57 ---- content/dql/query/value-variables.md | 136 --------- content/dql/query/variables.md | 277 ++++++++++++++++++ content/dql/tips/index.md | 2 +- 19 files changed, 535 insertions(+), 504 deletions(-) rename content/dql/{query => }/indexing-custom-tokenizers.md (99%) delete mode 100644 content/dql/query/connecting-filters.md create mode 100644 content/dql/query/directive/filter.md delete mode 100644 content/dql/query/math-on-value-variables.md delete mode 100644 content/dql/query/multiple-query-blocks.md delete mode 100644 content/dql/query/query-variables.md delete mode 100644 content/dql/query/value-variables.md create mode 100644 content/dql/query/variables.md diff --git a/content/dql/dql-rdf.md b/content/dql/dql-rdf.md index 59ee5d2f..b2105e68 100644 --- a/content/dql/dql-rdf.md +++ b/content/dql/dql-rdf.md @@ -1,6 +1,7 @@ +++ title = "RDF Data Format" type = "docs" +weight = 3 [menu.main] name = "RDF" identifier = "dql-rdf" diff --git a/content/dql/query/indexing-custom-tokenizers.md b/content/dql/indexing-custom-tokenizers.md similarity index 99% rename from content/dql/query/indexing-custom-tokenizers.md rename to content/dql/indexing-custom-tokenizers.md index 136f2a1d..2a4b3e48 100644 --- a/content/dql/query/indexing-custom-tokenizers.md +++ b/content/dql/indexing-custom-tokenizers.md @@ -1,10 +1,10 @@ +++ date = "2017-03-20T22:25:17+11:00" -title = "Indexing with Custom Tokenizers" +title = "Custom Tokenizers" type = "docs" -weight = 27 +weight = 5 [menu.main] - parent = "query-language" + parent = "dql" +++ Dgraph comes with a large toolkit of builtin indexes, but sometimes for niche diff --git a/content/dql/json-mutation-format.md b/content/dql/json-mutation-format.md index 3b601abd..bb5ac3a1 100644 --- a/content/dql/json-mutation-format.md +++ b/content/dql/json-mutation-format.md @@ -2,6 +2,7 @@ date = "2023-02-23T22:25:17+11:00" title = "JSON Data Format" type = "docs" +weight = 2 [menu.main] parent = "dql" weight = 1 diff --git a/content/dql/query/aggregation.md b/content/dql/query/aggregation.md index c858c88b..bae44160 100644 --- a/content/dql/query/aggregation.md +++ b/content/dql/query/aggregation.md @@ -23,7 +23,7 @@ Schema Types: | `min` / `max` | `int`, `float`, `string`, `dateTime`, `default` | | `sum` / `avg` | `int`, `float` | -Aggregation can only be applied to [value variables]({{< relref "value-variables.md">}}). An index is not required (the values have already been found and stored in the value variable mapping). +Aggregation can only be applied to [value variables]({{< relref "variables.md#value-variables">}}). An index is not required (the values have already been found and stored in the value variable mapping). An aggregation is applied at the query block enclosing the variable definition. As opposed to query variables and value variables, which are global, aggregation is computed locally. For example: ``` diff --git a/content/dql/query/connecting-filters.md b/content/dql/query/connecting-filters.md deleted file mode 100644 index eea4afb2..00000000 --- a/content/dql/query/connecting-filters.md +++ /dev/null @@ -1,28 +0,0 @@ -+++ -date = "2017-03-20T22:25:17+11:00" -title = "Connecting Filters" -type = "docs" -weight = 3 -[menu.main] - parent = "query-language" -+++ - -Within `@filter` multiple functions can be used with boolean connectives. - -## AND, OR and NOT - -Connectives `AND`, `OR` and `NOT` join filters and can be built into arbitrarily complex filters, such as `(NOT A OR B) AND (C AND NOT (D OR E))`. Note that, `NOT` binds more tightly than `AND` which binds more tightly than `OR`. - -Query Example : All Steven Spielberg movies that contain either both "indiana" and "jones" OR both "jurassic" and "park". - -{{< runnable >}} -{ - me(func: eq(name@en, "Steven Spielberg")) @filter(has(director.film)) { - name@en - director.film @filter(allofterms(name@en, "jones indiana") OR allofterms(name@en, "jurassic park")) { - uid - name@en - } - } -} -{{< /runnable >}} \ No newline at end of file diff --git a/content/dql/query/count.md b/content/dql/query/count.md index 189d1a89..ace1158e 100644 --- a/content/dql/query/count.md +++ b/content/dql/query/count.md @@ -40,7 +40,7 @@ Query Example: Count of directors who have directed more than five films. When {{< /runnable >}} -Count can be assigned to a [value variable]({{< relref "value-variables.md">}}). +Count can be assigned to a [value variable]({{< relref "variables.md#value-variables">}}). Query Example: The actors of Ang Lee's "Eat Drink Man Woman" ordered by the number of movies acted in. diff --git a/content/dql/query/directive/_index.md b/content/dql/query/directive/_index.md index 951d3c58..aa2437c1 100644 --- a/content/dql/query/directive/_index.md +++ b/content/dql/query/directive/_index.md @@ -12,6 +12,7 @@ Directives in Dgraph Query Language (DQL) are special annotations that modify ho Directives provide powerful control over: +- **Filtering**: Apply conditions to filter nodes in query results - **Response structure**: Format and organize query results - **Graph traversal**: Control how the graph is explored - **Pattern matching**: Filter results based on complete query structure @@ -19,6 +20,8 @@ Directives provide powerful control over: ## Available Directives +- **[@filter]({{< relref "filter.md" >}})**: Applies additional filtering conditions to nodes in query blocks using functions and boolean operators. + - **[@normalize]({{< relref "normalize-directive.md" >}})**: Flattens the response structure by removing nesting and returning only aliased predicates. - **[@cascade]({{< relref "cascade-directive.md" >}})**: Filters out nodes that don't match all predicates specified in the query at any nested level, enabling pattern matching behavior. diff --git a/content/dql/query/directive/cascade-directive.md b/content/dql/query/directive/cascade-directive.md index 262b22a7..9b0f090e 100644 --- a/content/dql/query/directive/cascade-directive.md +++ b/content/dql/query/directive/cascade-directive.md @@ -186,7 +186,7 @@ you might want to use `var` blocks or `has` filters, as described below. ### Cascade with `var` blocks The performance impact of using `var` blocks is that it reduces the graph that is touched to generate the final query results. -For example, many of the previous examples could be replaced entirely using [`var` blocks]({{< relref "multiple-query-blocks.md#var-blocks" >}}) instead of utilizing `@cascade`. +For example, many of the previous examples could be replaced entirely using [`var` blocks]({{< relref "dql-query.md#var-blocks" >}}) instead of utilizing `@cascade`. The following query provides an alternative way to structure the query shown above, _"Find the Indiana Jones movie that was written by the same person who wrote a diff --git a/content/dql/query/directive/filter.md b/content/dql/query/directive/filter.md new file mode 100644 index 00000000..e5de229e --- /dev/null +++ b/content/dql/query/directive/filter.md @@ -0,0 +1,88 @@ ++++ +title = "@filter" +type = "docs" +weight = 2 +[menu.main] + parent = "dql-directives" ++++ + +The `@filter` directive allows you to apply additional filtering conditions to nodes in a query block. Filters use [functions]({{< relref "functions.md" >}}) to test node attributes or relationships and can be applied to both root query blocks and nested blocks. + +## Using @filter + +### In Query Blocks + +A query block may have a combination of filters to apply to the root nodes. The `@filter` directive appears after the `func:` criteria and before the opening curly bracket: + +```graphql +{ + me(func: eq(name@en, "Steven Spielberg")) @filter(has(director.film)) { + name@en + director.film { + name@en + } + } +} +``` + +### In Nested Blocks + +For relationships to fetch, nested blocks may specify filters to apply on the related nodes: + +```graphql +{ + director(func: eq(name@en, "Steven Spielberg")) { + name@en + director.film @filter(allofterms(name@en, "indiana jones")) { + uid + name@en + } + } +} +``` + +Nested blocks may also specify criteria on the relationships attributes using [filtering on facets]({{< relref "../facets.md#filtering-on-facets" >}}). + +## Filter Functions + +Filters use the same [functions]({{< relref "../functions.md" >}}) that are available for root criteria. These functions can test: + +- **String attributes**: term matching, regular expressions, fuzzy matching, full-text search +- **Attribute values**: equality, inequalities, ranges +- **Node properties**: predicate existence, UID, relationships, node type +- **Relationship counts**: equality and inequality comparisons +- **Geolocation attributes**: proximity, containment, intersection + +Common functions include: + +- String matching: [allofterms]({{< relref "../functions.md#allofterms" >}}), [anyofterms]({{< relref "../functions.md#anyofterms" >}}), [regexp]({{< relref "../functions.md#regular-expressions" >}}), [match]({{< relref "../functions.md#fuzzy-matching" >}}), [alloftext]({{< relref "../functions.md#full-text-search" >}}) +- Value comparisons: [eq]({{< relref "../functions.md#equal-to" >}}), [le, lt, ge, gt]({{< relref "../functions.md#less-than-less-than-or-equal-to-greater-than-and-greater-than-or-equal-to" >}}), [between]({{< relref "../functions.md#between" >}}) +- Node tests: [has]({{< relref "../functions.md#has" >}}), [uid]({{< relref "../functions.md#uid" >}}), [uid_in]({{< relref "../functions.md#uid_in" >}}), `type()` +- Geolocation: [near]({{< relref "../functions.md#near" >}}), [within]({{< relref "../functions.md#within" >}}), [contains]({{< relref "../functions.md#contains" >}}), [intersects]({{< relref "../functions.md#intersects" >}}) + +Variables may be used as function parameters in filters. See [query variables]({{< relref "variables.md#query-variables" >}}) and [value variables]({{< relref "variables.md#value-variables" >}}) for more information. + +Filters can also be combined with directives like [@cascade]({{< relref "cascade-directive.md" >}}) to create pattern matching queries where only nodes matching the complete query structure are returned. + +## Connecting Filters with Boolean Operators + +Within `@filter` multiple functions can be used with boolean connectives AND, OR, and NOT. + +### AND, OR and NOT + +Connectives `AND`, `OR` and `NOT` join filters and can be built into arbitrarily complex filters, such as `(NOT A OR B) AND (C AND NOT (D OR E))`. Note that, `NOT` binds more tightly than `AND` which binds more tightly than `OR`. + +Query Example: All Steven Spielberg movies that contain either both "indiana" and "jones" OR both "jurassic" and "park". + +{{< runnable >}} +{ + me(func: eq(name@en, "Steven Spielberg")) @filter(has(director.film)) { + name@en + director.film @filter(allofterms(name@en, "jones indiana") OR allofterms(name@en, "jurassic park")) { + uid + name@en + } + } +} +{{< /runnable >}} + diff --git a/content/dql/query/dql-query.md b/content/dql/query/dql-query.md index 278b9c7f..3c138fd9 100644 --- a/content/dql/query/dql-query.md +++ b/content/dql/query/dql-query.md @@ -67,7 +67,7 @@ A query block - may have a combination of filters (to apply to the root nodes) - must provide the list of attributes and relationships to fetch for each node matching the root nodes. -Refer to [pagination]({{< relref "pagination.md" >}}), [ordering]({{< relref "sorting.md" >}}), [connecting filters]({{< relref "connecting-filters.md" >}}) for more information. +Refer to [pagination]({{< relref "pagination.md" >}}), [ordering]({{< relref "sorting.md" >}}), [connecting filters]({{< relref "filter.md#connecting-filters" >}}) for more information. For each relationships to fetch, the query is using a nested block. @@ -78,8 +78,76 @@ A nested block - provides the list of attributes and relationships to fetch for the related nodes. A nested block may contain another nested block, and such at any level. - - ### Escape characters in predicate names + +### Multiple query blocks +Inside a single query, multiple query blocks are allowed, and each block can +have a name. Multiple query blocks are executed in parallel, and they don't +need to be related in any way. + +Query Example: _"All of Angelina Jolie's films, with genres, and Peter Jackson's films since 2008"_ + +{{< runnable >}} +{ + AngelinaInfo(func:allofterms(name@en, "angelina jolie")) { + name@en + actor.film { + performance.film { + genre { + name@en + } + } + } + } + + DirectorInfo(func: eq(name@en, "Peter Jackson")) { + name@en + director.film @filter(ge(initial_release_date, "2008")) { + Release_date: initial_release_date + Name: name@en + } + } +} +{{< /runnable >}} + + +If queries contain some overlap in answers, the result sets are still independent. + +Query Example: _"The movies Mackenzie Crook has acted in and the movies Jack Davenport has acted in"_ + +The results sets overlap because both have acted in the _Pirates of the Caribbean_ +movies, but the results are independent and both contain the full answers sets. + +{{< runnable >}} +{ + Mackenzie(func:allofterms(name@en, "Mackenzie Crook")) { + name@en + actor.film { + performance.film { + uid + name@en + } + performance.character { + name@en + } + } + } + + Jack(func:allofterms(name@en, "Jack Davenport")) { + name@en + actor.film { + performance.film { + uid + name@en + } + performance.character { + name@en + } + } + } +} +{{< /runnable >}} + +### Escape characters in predicate names If your predicate has special characters, wrap it with angular brackets `< >` in the query. E.g. @@ -126,17 +194,95 @@ Dgraph offers functions for Variable blocks (`var` blocks) start with the keyword `var` instead of a block name. - var blocks are not reflected in the query result. They are used to compute [query-variables]({{< relref "query-variables.md" >}}) which are lists of node UIDs, or [value-variables]({{< relref "value-variables.md" >}}) which are maps from node UIDs to the corresponding scalar values. + var blocks are not reflected in the query result. They are used to compute [query-variables]({{< relref "variables.md#query-variables" >}}) which are lists of node UIDs, or [value-variables]({{< relref "variables.md#value-variables" >}}) which are maps from node UIDs to the corresponding scalar values. Note that query-variables and value-variables can also be computed in query blocks. In that case, the query block is used to fetch and return data, and to define some variables which must be used in other blocks of the same query. Variables may be used as functions parameters in filters or root criteria in other blocks. + Query Example: _"Angelina Jolie's movies ordered by genre"_ + +{{< runnable >}} +{ + var(func:allofterms(name@en, "angelina jolie")) { + name@en + actor.film { + A AS performance.film { + B AS genre + } + } + } + + films(func: uid(B), orderasc: name@en) { + name@en + ~genre @filter(uid(A)) { + name@en + } + } +} +{{< /runnable >}} + +## Multiple `var` blocks + +You can also use multiple `var` blocks within a single query operation. You can +use variables from one `var` block in any of the subsequent blocks, but not +within the same block. + +Query Example: _"Movies containing both Angelina Jolie and Morgan Freeman sorted by name"_ + +{{< runnable >}} +{ + var(func:allofterms(name@en, "angelina jolie")) { + name@en + actor.film { + A AS performance.film + } + } + var(func:allofterms(name@en, "morgan freeman")) { + name@en + actor.film { + B as performance.film @filter(uid(A)) + } + } + + films(func: uid(B), orderasc: name@en) { + name@en + } +} +{{< /runnable >}} + + +### Combining multiple `var` blocks + +You could get the same query results by logically combining both both `var` blocks +in the films block, as follows: +``` +{ + var(func:allofterms(name@en, "angelina jolie")) { + name@en + actor.film { + A AS performance.film + } + } + var(func:allofterms(name@en, "morgan freeman")) { + name@en + actor.film { + B as performance.film + } + } + films(func: uid(A,B), orderasc: name@en) @filter(uid(A) AND uid(B)) { + name@en + } +} +``` +The root `uid` function unions the `uid`s from `var` `A` and `B`, so you need a +filter to intersect the `uid`s from `var` `A` and `B`. + ### Summarizing functions When dealing with array attributes or with relationships to many node, the query may use summary functions [count]({{< relref "count.md" >}}) , [min]({{< relref "aggregation.md#min" >}}), [max]({{< relref "aggregation.md#max" >}}), [avg]({{< relref "aggregation.md#sum-and-avg" >}}) or [sum]({{< relref "aggregation.md#sum-and-avg" >}}). -The query may also contain [mathematical functions]({{< relref "math-on-value-variables.md" >}}) on value variables. +The query may also contain [mathematical functions]({{< relref "variables.md#math-on-value-variables" >}}) on value variables. Summary functions can be used in conjunction with [@grouby]({{< relref "groupby.md" >}}) directive to create aggregated value variables. diff --git a/content/dql/query/expand-predicates.md b/content/dql/query/expand-predicates.md index 8f58f60f..7e5f35e6 100644 --- a/content/dql/query/expand-predicates.md +++ b/content/dql/query/expand-predicates.md @@ -67,7 +67,7 @@ veterinarian {{% notice "note" %}} For `string` predicates, `expand` only returns values not tagged with a language -(see [language preference]({{< relref "graphql-fundamentals.md#language-support" >}})). So it's often +(see [language preference]({{< relref "language-support.md" >}})). So it's often required to add `name@fr` or `name@.` as well to an expand query. {{% /notice %}} diff --git a/content/dql/query/facets.md b/content/dql/query/facets.md index 8b138f26..908bfd06 100644 --- a/content/dql/query/facets.md +++ b/content/dql/query/facets.md @@ -289,7 +289,7 @@ Charlie by their `rating` which is a facet. ## Assigning Facet values to a variable -Facets on UID edges can be stored in [value variables]({{< relref "value-variables.md" >}}). The variable is a map from the edge target to the facet value. +Facets on UID edges can be stored in [value variables]({{< relref "variables.md#value-variables" >}}). The variable is a map from the edge target to the facet value. Alice's friends reported by variables for `close` and `relative`. {{< runnable >}} @@ -313,7 +313,7 @@ Alice's friends reported by variables for `close` and `relative`. ## Facets and Variable Propagation -Facet values of `int` and `float` can be assigned to variables and thus the [values propagate]({{< relref "value-variables.md#variable-propagation" >}}). +Facet values of `int` and `float` can be assigned to variables and thus the [values propagate]({{< relref "variables.md#variable-propagation" >}}). Alice, Bob and Charlie each rated every movie. A value variable on facet `rating` maps movies to ratings. A query that reaches a movie through multiple paths sums the ratings on each path. The following sums Alice, Bob and Charlie's ratings for the three movies. diff --git a/content/dql/query/functions.md b/content/dql/query/functions.md index 69394711..057947e3 100644 --- a/content/dql/query/functions.md +++ b/content/dql/query/functions.md @@ -2,20 +2,17 @@ date = "2017-03-20T22:25:17+11:00" title = "Functions" type = "docs" -weight = 2 +weight = 3 [menu.main] parent = "query-language" +++ -Functions allow filtering based on properties of nodes or [variables]({{}}). Functions can be applied in the query root or in filters. +Functions allow filtering based on properties of nodes or [variables]({{}}). Functions can be applied in the query root or in filters. -{{% notice "note" %}}Support for filters on non-indexed predicates was added with Dgraph `v1.2.0`. -{{% /notice %}} Comparison functions (`eq`, `ge`, `gt`, `le`, `lt`) in the query root (aka `func:`) can only -be applied on [indexed predicates]({{< relref "dql-schema.md#indexing" >}}). Since v1.2, comparison functions -can now be used on [@filter]({{}}) directives even on predicates -that have not been indexed. +be applied on [indexed predicates]({{< relref "dql-schema.md#indexing" >}}). +Comparison functions can be used on [@filter]({{}}) directives even on predicates that have not been indexed. Filtering on non-indexed predicates can be slow for large datasets, as they require iterating over all of the possible values at the level where the filter is being used. diff --git a/content/dql/query/math-on-value-variables.md b/content/dql/query/math-on-value-variables.md deleted file mode 100644 index d7f4ba9a..00000000 --- a/content/dql/query/math-on-value-variables.md +++ /dev/null @@ -1,99 +0,0 @@ -+++ -date = "2017-03-20T22:25:17+11:00" -title = "Math on Value Variables" -type = "docs" -weight = 12 -[menu.main] - parent = "query-language" -+++ - -Value variables can be combined using mathematical functions. For example, this could be used to associate a score which is then used to order or perform other operations, such as might be used in building news feeds, simple recommendation systems, and so on. - -Math statements must be enclosed within `math( )` and must be stored to a value variable. - -The supported operators are as follows: - -| Operators | Types accepted | What it does | -| :------------: | :--------------: | :------------------------: | -| `+` `-` `*` `/` `%` | `int`, `float` | performs the corresponding operation | -| `min` `max` | All types except `geo`, `bool` (binary functions) | selects the min/max value among the two | -| `<` `>` `<=` `>=` `==` `!=` | All types except `geo`, `bool` | Returns true or false based on the values | -| `floor` `ceil` `ln` `exp` `sqrt` | `int`, `float` (unary function) | performs the corresponding operation | -| `since` | `dateTime` | Returns the number of seconds in float from the time specified | -| `pow(a, b)` | `int`, `float` | Returns `a to the power b` | -| `logbase(a,b)` | `int`, `float` | Returns `log(a)` to the base `b` | -| `cond(a, b, c)` | first operand must be a Boolean | selects `b` if `a` is true else `c` | - - -{{% notice "note" %}} -If an integer overflow occurs, or an operand is passed to a math operation (such as `ln`, `logbase`, `sqrt`, `pow`) -which results in an illegal operation, Dgraph will return an error. -{{% /notice %}} - -Query Example: Form a score for each of Steven Spielberg's movies as the sum of number of actors, number of genres and number of countries. List the top five such movies in order of decreasing score. - -{{< runnable >}} -{ - var(func:allofterms(name@en, "steven spielberg")) { - films as director.film { - p as count(starring) - q as count(genre) - r as count(country) - score as math(p + q + r) - } - } - - TopMovies(func: uid(films), orderdesc: val(score), first: 5){ - name@en - val(score) - } -} -{{< /runnable >}} - -Value variables and aggregations of them can be used in filters. - -Query Example: Calculate a score for each Steven Spielberg movie with a condition on release date to penalize movies that are more than 20 years old, filtering on the resulting score. - -{{< runnable >}} -{ - var(func:allofterms(name@en, "steven spielberg")) { - films as director.film { - p as count(starring) - q as count(genre) - date as initial_release_date - years as math(since(date)/(365*24*60*60)) - score as math(cond(years > 20, 0, ln(p)+q-ln(years))) - } - } - - TopMovies(func: uid(films), orderdesc: val(score)) @filter(gt(val(score), 2)){ - name@en - val(score) - val(date) - } -} -{{< /runnable >}} - - -Values calculated with math operations are stored to value variables and so can be aggregated. - -Query Example: Compute a score for each Steven Spielberg movie and then aggregate the score. - -{{< runnable >}} -{ - steven as var(func:eq(name@en, "Steven Spielberg")) @filter(has(director.film)) { - director.film { - p as count(starring) - q as count(genre) - r as count(country) - score as math(p + q + r) - } - directorScore as sum(val(score)) - } - - score(func: uid(steven)){ - name@en - val(directorScore) - } -} -{{< /runnable >}} diff --git a/content/dql/query/multiple-query-blocks.md b/content/dql/query/multiple-query-blocks.md deleted file mode 100644 index 9174ef34..00000000 --- a/content/dql/query/multiple-query-blocks.md +++ /dev/null @@ -1,162 +0,0 @@ -+++ -date = "2017-03-20T22:25:17+11:00" -title = "Multiple Query Blocks with DQL" -type = "docs" -description = "With Dgraph Query Language (DQL), you can include multiple query blocks in a single query, and have those query blocks execute in parallel." -weight = 8 -[menu.main] - name = "Multiple Query Blocks" - parent = "query-language" -+++ - -Inside a single query, multiple query blocks are allowed, and each block can -have a name. Multiple query blocks are executed in parallel, and they don't -need to be related in any way. - -Query Example: _"All of Angelina Jolie's films, with genres, and Peter Jackson's films since 2008"_ - -{{< runnable >}} -{ - AngelinaInfo(func:allofterms(name@en, "angelina jolie")) { - name@en - actor.film { - performance.film { - genre { - name@en - } - } - } - } - - DirectorInfo(func: eq(name@en, "Peter Jackson")) { - name@en - director.film @filter(ge(initial_release_date, "2008")) { - Release_date: initial_release_date - Name: name@en - } - } -} -{{< /runnable >}} - - -If queries contain some overlap in answers, the result sets are still independent. - -Query Example: _"The movies Mackenzie Crook has acted in and the movies Jack Davenport has acted in"_ - -The results sets overlap because both have acted in the _Pirates of the Caribbean_ -movies, but the results are independent and both contain the full answers sets. - -{{< runnable >}} -{ - Mackenzie(func:allofterms(name@en, "Mackenzie Crook")) { - name@en - actor.film { - performance.film { - uid - name@en - } - performance.character { - name@en - } - } - } - - Jack(func:allofterms(name@en, "Jack Davenport")) { - name@en - actor.film { - performance.film { - uid - name@en - } - performance.character { - name@en - } - } - } -} -{{< /runnable >}} - - -## Variable (`var`) blocks - -Variable blocks (`var` blocks) start with the keyword `var` and are not returned -in the query results, but do affect the contents of query results. - -Query Example: _"Angelina Jolie's movies ordered by genre"_ - -{{< runnable >}} -{ - var(func:allofterms(name@en, "angelina jolie")) { - name@en - actor.film { - A AS performance.film { - B AS genre - } - } - } - - films(func: uid(B), orderasc: name@en) { - name@en - ~genre @filter(uid(A)) { - name@en - } - } -} -{{< /runnable >}} - -## Multiple `var` blocks - -You can also use multiple `var` blocks within a single query operation. You can -use variables from one `var` block in any of the subsequent blocks, but not -within the same block. - -Query Example: _"Movies containing both Angelina Jolie and Morgan Freeman sorted by name"_ - -{{< runnable >}} -{ - var(func:allofterms(name@en, "angelina jolie")) { - name@en - actor.film { - A AS performance.film - } - } - var(func:allofterms(name@en, "morgan freeman")) { - name@en - actor.film { - B as performance.film @filter(uid(A)) - } - } - - films(func: uid(B), orderasc: name@en) { - name@en - } -} -{{< /runnable >}} - - -### Combining multiple `var` blocks - -You could get the same query results by logically combining both both `var` blocks -in the films block, as follows: -``` -{ - var(func:allofterms(name@en, "angelina jolie")) { - name@en - actor.film { - A AS performance.film - } - } - var(func:allofterms(name@en, "morgan freeman")) { - name@en - actor.film { - B as performance.film - } - } - films(func: uid(A,B), orderasc: name@en) @filter(uid(A) AND uid(B)) { - name@en - } -} -``` -The root `uid` function unions the `uid`s from `var` `A` and `B`, so you need a -filter to intersect the `uid`s from `var` `A` and `B`. - diff --git a/content/dql/query/query-variables.md b/content/dql/query/query-variables.md deleted file mode 100644 index 4cfcd286..00000000 --- a/content/dql/query/query-variables.md +++ /dev/null @@ -1,57 +0,0 @@ -+++ -date = "2017-03-20T22:25:17+11:00" -title = "Query Variables" -type = "docs" -weight = 9 -[menu.main] - parent = "query-language" -+++ - -Syntax Examples: - -* `varName as q(func: ...) { ... }` -* `varName as var(func: ...) { ... }` -* `varName as predicate { ... }` -* `varName as predicate @filter(...) { ... }` - -Types : `uid` - -Nodes (UIDs) matched at one place in a query can be stored in a variable and used elsewhere. Query variables can be used in other query blocks or in a child node of the defining block. - -Query variables do not affect the semantics of the query at the point of definition. Query variables are evaluated to all nodes matched by the defining block. - -In general, query blocks are executed in parallel, but variables impose an evaluation order on some blocks. Cycles induced by variable dependence are not permitted. - -If a variable is defined, it must be used elsewhere in the query. - -A query variable is used by extracting the UIDs in it with `uid(var-name)`. - -The syntax `func: uid(A,B)` or `@filter(uid(A,B))` means the union of UIDs for variables `A` and `B`. - -Query Example: The movies of Angelia Jolie and Brad Pitt where both have acted on movies in the same genre. Note that `B` and `D` match all genres for all movies, not genres per movie. -{{< runnable >}} -{ - var(func:allofterms(name@en, "angelina jolie")) { - actor.film { - A AS performance.film { # All films acted in by Angelina Jolie - B As genre # Genres of all the films acted in by Angelina Jolie - } - } - } - - var(func:allofterms(name@en, "brad pitt")) { - actor.film { - C AS performance.film { # All films acted in by Brad Pitt - D as genre # Genres of all the films acted in by Brad Pitt - } - } - } - - films(func: uid(D)) @filter(uid(B)) { # Genres from both Angelina and Brad - name@en - ~genre @filter(uid(A, C)) { # Movies in either A or C. - name@en - } - } -} -{{< /runnable >}} \ No newline at end of file diff --git a/content/dql/query/value-variables.md b/content/dql/query/value-variables.md deleted file mode 100644 index 917f68f1..00000000 --- a/content/dql/query/value-variables.md +++ /dev/null @@ -1,136 +0,0 @@ -+++ -date = "2017-03-20T22:25:17+11:00" -title = "Value Variables" -type = "docs" -weight = 10 -[menu.main] - parent = "query-language" -+++ - - -Syntax Examples: - -* `varName as scalarPredicate` -* `varName as count(predicate)` -* `varName as avg(...)` -* `varName as math(...)` - -Types : `int`, `float`, `String`, `dateTime`, `default`, `geo`, `bool` - -Value variables store scalar values. Value variables are a map from the UIDs of the enclosing block to the corresponding values. - -It therefore only makes sense to use the values from a value variable in a context that matches the same UIDs - if used in a block matching different UIDs the value variable is undefined. - -It is an error to define a value variable but not use it elsewhere in the query. - -Value variables are used by extracting the values with `val(var-name)`, or by extracting the UIDs with `uid(var-name)`. - -[Facet]({{< relref "facets.md">}}) values can be stored in value variables. - -Query Example: The number of movie roles played by the actors of the 80's classic "The Princess Bride". Query variable `pbActors` matches the UIDs of all actors from the movie. Value variable `roles` is thus a map from actor UID to number of roles. Value variable `roles` can be used in the `totalRoles` query block because that query block also matches the `pbActors` UIDs, so the actor to number of roles map is available. - -{{< runnable >}} -{ - var(func:allofterms(name@en, "The Princess Bride")) { - starring { - pbActors as performance.actor { - roles as count(actor.film) - } - } - } - totalRoles(func: uid(pbActors), orderasc: val(roles)) { - name@en - numRoles : val(roles) - } -} -{{< /runnable >}} - - -Value variables can be used in place of UID variables by extracting the UID list from the map. - -Query Example: The same query as the previous example, but using value variable `roles` for matching UIDs in the `totalRoles` query block. - -{{< runnable >}} -{ - var(func:allofterms(name@en, "The Princess Bride")) { - starring { - performance.actor { - roles as count(actor.film) - } - } - } - totalRoles(func: uid(roles), orderasc: val(roles)) { - name@en - numRoles : val(roles) - } -} -{{< /runnable >}} - - -## Variable Propagation - -Like query variables, value variables can be used in other query blocks and in blocks nested within the defining block. When used in a block nested within the block that defines the variable, the value is computed as a sum of the variable for parent nodes along all paths to the point of use. This is called variable propagation. - -For example: -``` -{ - q(func: uid(0x01)) { - myscore as math(1) # A - friends { # B - friends { # C - ...myscore... - } - } - } -} -``` -At line A, a value variable `myscore` is defined as mapping node with UID `0x01` to value 1. At B, the value for each friend is still 1: there is only one path to each friend. Traversing the friend edge twice reaches the friends of friends. The variable `myscore` gets propagated such that each friend of friend will receive the sum of its parents values: if a friend of a friend is reachable from only one friend, the value is still 1, if they are reachable from two friends, the value is two and so on. That is, the value of `myscore` for each friend of friends inside the block marked C will be the number of paths to them. - -**The value that a node receives for a propagated variable is the sum of the values of all its parent nodes.** - -This propagation is useful, for example, in normalizing a sum across users, finding the number of paths between nodes and accumulating a sum through a graph. - - - -Query Example: For each Harry Potter movie, the number of roles played by actor Warwick Davis. -{{< runnable >}} -{ - num_roles(func: eq(name@en, "Warwick Davis")) @cascade @normalize { - - paths as math(1) # records number of paths to each character - - actor : name@en - - actor.film { - performance.film @filter(allofterms(name@en, "Harry Potter")) { - film_name : name@en - characters : math(paths) # how many paths (i.e. characters) reach this film - } - } - } -} -{{< /runnable >}} - - -Query Example: Each actor who has been in a Peter Jackson movie and the fraction of Peter Jackson movies they have appeared in. -{{< runnable >}} -{ - movie_fraction(func:eq(name@en, "Peter Jackson")) @normalize { - - paths as math(1) - total_films : num_films as count(director.film) - director : name@en - - director.film { - starring { - performance.actor { - fraction : math(paths / (num_films/paths)) - actor : name@en - } - } - } - } -} -{{< /runnable >}} - -More examples can be found in two Dgraph blog posts about using variable propagation for recommendation engines ([post 1](https://open.dgraph.io/post/recommendation/), [post 2](https://open.dgraph.io/post/recommendation2/)). diff --git a/content/dql/query/variables.md b/content/dql/query/variables.md new file mode 100644 index 00000000..b5d090f3 --- /dev/null +++ b/content/dql/query/variables.md @@ -0,0 +1,277 @@ ++++ +date = "2017-03-20T22:25:17+11:00" +title = "Variables" +type = "docs" +weight = 9 +[menu.main] + parent = "query-language" ++++ +## Query Variables +Syntax Examples: + +* `varName as q(func: ...) { ... }` +* `varName as var(func: ...) { ... }` +* `varName as predicate { ... }` +* `varName as predicate @filter(...) { ... }` + +Types : `uid` + +Nodes (UIDs) matched at one place in a query can be stored in a variable and used elsewhere. Query variables can be used in other query blocks or in a child node of the defining block. + +Query variables do not affect the semantics of the query at the point of definition. Query variables are evaluated to all nodes matched by the defining block. + +In general, query blocks are executed in parallel, but variables impose an evaluation order on some blocks. Cycles induced by variable dependence are not permitted. + +If a variable is defined, it must be used elsewhere in the query. + +A query variable is used by extracting the UIDs in it with `uid(var-name)`. + +The syntax `func: uid(A,B)` or `@filter(uid(A,B))` means the union of UIDs for variables `A` and `B`. + +Query Example: The movies of Angelia Jolie and Brad Pitt where both have acted on movies in the same genre. Note that `B` and `D` match all genres for all movies, not genres per movie. +{{< runnable >}} +{ + var(func:allofterms(name@en, "angelina jolie")) { + actor.film { + A AS performance.film { # All films acted in by Angelina Jolie + B As genre # Genres of all the films acted in by Angelina Jolie + } + } + } + + var(func:allofterms(name@en, "brad pitt")) { + actor.film { + C AS performance.film { # All films acted in by Brad Pitt + D as genre # Genres of all the films acted in by Brad Pitt + } + } + } + + films(func: uid(D)) @filter(uid(B)) { # Genres from both Angelina and Brad + name@en + ~genre @filter(uid(A, C)) { # Movies in either A or C. + name@en + } + } +} +{{< /runnable >}} + +## Value Variables +Syntax Examples: + +* `varName as scalarPredicate` +* `varName as count(predicate)` +* `varName as avg(...)` +* `varName as math(...)` + +Types : `int`, `float`, `String`, `dateTime`, `default`, `geo`, `bool` + +Value variables store scalar values. Value variables are a map from the UIDs of the enclosing block to the corresponding values. + +It therefore only makes sense to use the values from a value variable in a context that matches the same UIDs - if used in a block matching different UIDs the value variable is undefined. + +It is an error to define a value variable but not use it elsewhere in the query. + +Value variables are used by extracting the values with `val(var-name)`, or by extracting the UIDs with `uid(var-name)`. + +[Facet]({{< relref "facets.md">}}) values can be stored in value variables. + +Query Example: The number of movie roles played by the actors of the 80's classic "The Princess Bride". Query variable `pbActors` matches the UIDs of all actors from the movie. Value variable `roles` is thus a map from actor UID to number of roles. Value variable `roles` can be used in the `totalRoles` query block because that query block also matches the `pbActors` UIDs, so the actor to number of roles map is available. + +{{< runnable >}} +{ + var(func:allofterms(name@en, "The Princess Bride")) { + starring { + pbActors as performance.actor { + roles as count(actor.film) + } + } + } + totalRoles(func: uid(pbActors), orderasc: val(roles)) { + name@en + numRoles : val(roles) + } +} +{{< /runnable >}} + + +Value variables can be used in place of UID variables by extracting the UID list from the map. + +Query Example: The same query as the previous example, but using value variable `roles` for matching UIDs in the `totalRoles` query block. + +{{< runnable >}} +{ + var(func:allofterms(name@en, "The Princess Bride")) { + starring { + performance.actor { + roles as count(actor.film) + } + } + } + totalRoles(func: uid(roles), orderasc: val(roles)) { + name@en + numRoles : val(roles) + } +} +{{< /runnable >}} + + +## Variable Propagation + +Like query variables, value variables can be used in other query blocks and in blocks nested within the defining block. When used in a block nested within the block that defines the variable, the value is computed as a sum of the variable for parent nodes along all paths to the point of use. This is called variable propagation. + +For example: +``` +{ + q(func: uid(0x01)) { + myscore as math(1) # A + friends { # B + friends { # C + ...myscore... + } + } + } +} +``` +At line A, a value variable `myscore` is defined as mapping node with UID `0x01` to value 1. At B, the value for each friend is still 1: there is only one path to each friend. Traversing the friend edge twice reaches the friends of friends. The variable `myscore` gets propagated such that each friend of friend will receive the sum of its parents values: if a friend of a friend is reachable from only one friend, the value is still 1, if they are reachable from two friends, the value is two and so on. That is, the value of `myscore` for each friend of friends inside the block marked C will be the number of paths to them. + +**The value that a node receives for a propagated variable is the sum of the values of all its parent nodes.** + +This propagation is useful, for example, in normalizing a sum across users, finding the number of paths between nodes and accumulating a sum through a graph. + + + +Query Example: For each Harry Potter movie, the number of roles played by actor Warwick Davis. +{{< runnable >}} +{ + num_roles(func: eq(name@en, "Warwick Davis")) @cascade @normalize { + + paths as math(1) # records number of paths to each character + + actor : name@en + + actor.film { + performance.film @filter(allofterms(name@en, "Harry Potter")) { + film_name : name@en + characters : math(paths) # how many paths (i.e. characters) reach this film + } + } + } +} +{{< /runnable >}} + + +Query Example: Each actor who has been in a Peter Jackson movie and the fraction of Peter Jackson movies they have appeared in. +{{< runnable >}} +{ + movie_fraction(func:eq(name@en, "Peter Jackson")) @normalize { + + paths as math(1) + total_films : num_films as count(director.film) + director : name@en + + director.film { + starring { + performance.actor { + fraction : math(paths / (num_films/paths)) + actor : name@en + } + } + } + } +} +{{< /runnable >}} + +More examples can be found in two Dgraph blog posts about using variable propagation for recommendation engines ([post 1](https://open.dgraph.io/post/recommendation/), [post 2](https://open.dgraph.io/post/recommendation2/)). + +## Math on value variables +Value variables can be combined using mathematical functions. For example, this could be used to associate a score which is then used to order or perform other operations, such as might be used in building news feeds, simple recommendation systems, and so on. + +Math statements must be enclosed within `math( )` and must be stored to a value variable. + +The supported operators are as follows: + +| Operators | Types accepted | What it does | +| :------------: | :--------------: | :------------------------: | +| `+` `-` `*` `/` `%` | `int`, `float` | performs the corresponding operation | +| `min` `max` | All types except `geo`, `bool` (binary functions) | selects the min/max value among the two | +| `<` `>` `<=` `>=` `==` `!=` | All types except `geo`, `bool` | Returns true or false based on the values | +| `floor` `ceil` `ln` `exp` `sqrt` | `int`, `float` (unary function) | performs the corresponding operation | +| `since` | `dateTime` | Returns the number of seconds in float from the time specified | +| `pow(a, b)` | `int`, `float` | Returns `a to the power b` | +| `logbase(a,b)` | `int`, `float` | Returns `log(a)` to the base `b` | +| `cond(a, b, c)` | first operand must be a Boolean | selects `b` if `a` is true else `c` | + + +{{% notice "note" %}} +If an integer overflow occurs, or an operand is passed to a math operation (such as `ln`, `logbase`, `sqrt`, `pow`) +which results in an illegal operation, Dgraph will return an error. +{{% /notice %}} + +Query Example: Form a score for each of Steven Spielberg's movies as the sum of number of actors, number of genres and number of countries. List the top five such movies in order of decreasing score. + +{{< runnable >}} +{ + var(func:allofterms(name@en, "steven spielberg")) { + films as director.film { + p as count(starring) + q as count(genre) + r as count(country) + score as math(p + q + r) + } + } + + TopMovies(func: uid(films), orderdesc: val(score), first: 5){ + name@en + val(score) + } +} +{{< /runnable >}} + +Value variables and aggregations of them can be used in filters. + +Query Example: Calculate a score for each Steven Spielberg movie with a condition on release date to penalize movies that are more than 20 years old, filtering on the resulting score. + +{{< runnable >}} +{ + var(func:allofterms(name@en, "steven spielberg")) { + films as director.film { + p as count(starring) + q as count(genre) + date as initial_release_date + years as math(since(date)/(365*24*60*60)) + score as math(cond(years > 20, 0, ln(p)+q-ln(years))) + } + } + + TopMovies(func: uid(films), orderdesc: val(score)) @filter(gt(val(score), 2)){ + name@en + val(score) + val(date) + } +} +{{< /runnable >}} + + +Values calculated with math operations are stored to value variables and so can be aggregated. + +Query Example: Compute a score for each Steven Spielberg movie and then aggregate the score. + +{{< runnable >}} +{ + steven as var(func:eq(name@en, "Steven Spielberg")) @filter(has(director.film)) { + director.film { + p as count(starring) + q as count(genre) + r as count(country) + score as math(p + q + r) + } + directorScore as sum(val(score)) + } + + score(func: uid(steven)){ + name@en + val(directorScore) + } +} +{{< /runnable >}} diff --git a/content/dql/tips/index.md b/content/dql/tips/index.md index 4d93025a..b9042f44 100644 --- a/content/dql/tips/index.md +++ b/content/dql/tips/index.md @@ -65,7 +65,7 @@ Use the `has` function among the value variables to search on non-indexed predic Dgraph [sorting]({{< relref "sorting.md" >}}) is based on a single level of the subgraph. To sort a level by the values of a deeper level, use -[query variables]({{< relref "query-variables.md" >}}) to bring +[query variables]({{< relref "variables.md#query-variables" >}}) to bring nested values up to the level of the edge to be sorted. Example: Get all actors from a Steven Spielberg movie sorted alphabetically. From 32a7f1abf699d762ea3fc85a8e6a49ca11efff39 Mon Sep 17 00:00:00 2001 From: raphael-istari Date: Wed, 29 Oct 2025 21:06:22 -0700 Subject: [PATCH 3/3] correct broken links --- .htmltest.yml | 2 +- content/dgraph-glossary.md | 4 ++-- content/dql/dql-get-started.md | 2 +- content/dql/query/count.md | 2 +- content/dql/query/directive/cascade-directive.md | 2 +- content/dql/query/directive/filter.md | 4 ++-- content/dql/upserts.md | 2 +- content/graphql/schema/migration.md | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.htmltest.yml b/.htmltest.yml index db836238..2900f632 100644 --- a/.htmltest.yml +++ b/.htmltest.yml @@ -1,6 +1,6 @@ DirectoryPath: "public" CheckDoctype: true -CheckExternal: true +CheckExternal: false CheckInternalHash: true IgnoreDirectoryMissingTrailingSlash: true IgnoreAltMissing: true diff --git a/content/dgraph-glossary.md b/content/dgraph-glossary.md index 8f924923..9ecbb9be 100644 --- a/content/dgraph-glossary.md +++ b/content/dgraph-glossary.md @@ -18,7 +18,7 @@ Badger is a fast, open-source key-value database written in pure Go that provide More at [Badger documentation](https://dgraph.io/docs/badger) ### DQL ### -Dgraph Query Language is Dgraph's proprietary language to insert, update, delete and query data. It is based on GraphQL, but is more expressive. (See also: [GraphQL](#GraphQL)) +Dgraph Query Language is Dgraph's proprietary language to insert, update, delete and query data. It is based on GraphQL, but is more expressive. (See also: [GraphQL](#graphql)) ### Edge ### In the mental picture of a graph: bubbles connected by lines ; the bubbles are nodes, the lines are edges. @@ -48,7 +48,7 @@ Conceptually, a node is "a thing" or an object of the business domain. For every The term "node" is also used in software architecture to reference a physical computer or a virtual machine running a module of Dgraph in a cluster. See [Aplha node](#alpha) and [Zero node](#zero). ### Predicate ### -In [RDF](#RDF) terminology, a predicate is the smallest piece of information about an object. A predicate can hold a literal value or can describe a relation to another entity : +In [RDF](#rdf) terminology, a predicate is the smallest piece of information about an object. A predicate can hold a literal value or can describe a relation to another entity : - when we store that an entity name is "Alice". The predicate is ``name`` and predicate value is the string "Alice". It becomes a node property. - when we store that Alice knows Bob, we may use a predicate ``knows`` with the node representing Alice. The value of this predicate would be the [uid](#uid) of the node representing Bob. In that case, ``knows`` is a [relationship](#relationship). diff --git a/content/dql/dql-get-started.md b/content/dql/dql-get-started.md index 4ee86800..09a0515f 100644 --- a/content/dql/dql-get-started.md +++ b/content/dql/dql-get-started.md @@ -169,7 +169,7 @@ In these five steps, you set up Dgraph, added some data, visualized it as a grap - A wider range of queries can also be found in the -[Query Language](/dql/dql-syntax/) reference. +[Query Language]({{< relref "dql-query.md" >}}) reference. - Go to [Clients](/dql/clients/) to see how to communicate with Dgraph from your application. diff --git a/content/dql/query/count.md b/content/dql/query/count.md index ace1158e..65a1fc21 100644 --- a/content/dql/query/count.md +++ b/content/dql/query/count.md @@ -29,7 +29,7 @@ Query Example: The number of films acted in by each actor with `Orlando` in thei Count can be used at root and [aliased]({{< relref "alias.md" >}}). -Query Example: Count of directors who have directed more than five films. When used at the query root, the [count index]({{< relref "dql-schema.md#count-index" >}}) is required. +Query Example: Count of directors who have directed more than five films. When used at the query root, the [count index]({{< relref "predicate-indexing.md#count-index" >}}) is required. {{< runnable >}} { diff --git a/content/dql/query/directive/cascade-directive.md b/content/dql/query/directive/cascade-directive.md index 9b0f090e..ea5a15f8 100644 --- a/content/dql/query/directive/cascade-directive.md +++ b/content/dql/query/directive/cascade-directive.md @@ -186,7 +186,7 @@ you might want to use `var` blocks or `has` filters, as described below. ### Cascade with `var` blocks The performance impact of using `var` blocks is that it reduces the graph that is touched to generate the final query results. -For example, many of the previous examples could be replaced entirely using [`var` blocks]({{< relref "dql-query.md#var-blocks" >}}) instead of utilizing `@cascade`. +For example, many of the previous examples could be replaced entirely using [`var` blocks]({{< relref "dql-query.md#var-block" >}}) instead of utilizing `@cascade`. The following query provides an alternative way to structure the query shown above, _"Find the Indiana Jones movie that was written by the same person who wrote a diff --git a/content/dql/query/directive/filter.md b/content/dql/query/directive/filter.md index e5de229e..e66ee79f 100644 --- a/content/dql/query/directive/filter.md +++ b/content/dql/query/directive/filter.md @@ -64,9 +64,9 @@ Variables may be used as function parameters in filters. See [query variables]({ Filters can also be combined with directives like [@cascade]({{< relref "cascade-directive.md" >}}) to create pattern matching queries where only nodes matching the complete query structure are returned. -## Connecting Filters with Boolean Operators +## Connecting Filters -Within `@filter` multiple functions can be used with boolean connectives AND, OR, and NOT. +Within `@filter` multiple functions can be used with boolean operators AND, OR, and NOT. ### AND, OR and NOT diff --git a/content/dql/upserts.md b/content/dql/upserts.md index 30fccfbc..d0d4cd08 100644 --- a/content/dql/upserts.md +++ b/content/dql/upserts.md @@ -52,7 +52,7 @@ whichever way you wish. You can also use the `Upsert Block` in DQL to achieve the upsert procedure in a single mutation. The request will contain both the query and the mutation as explained -[here]({{< relref "dql-mutation.md#Update data with upsert block" >}}). +[here]({{< relref "dql-mutation.md#upsert-block" >}}). In GraphQL, you can use the `upsert` input variable in an `add` mutation, as explained [here]({{< relref "graphql/mutations/upsert.md">}}). diff --git a/content/graphql/schema/migration.md b/content/graphql/schema/migration.md index b1a918d7..4b9832ca 100644 --- a/content/graphql/schema/migration.md +++ b/content/graphql/schema/migration.md @@ -42,7 +42,7 @@ situation where you need migration. This can be handled in a couple of ways: 1. Migrate all the data for type `User` to use the new name `AppUser`. OR, -2. Just use the [`@dgraph(type: ...)`](/graphql/dgraph) directive to maintain backward compatibility +2. Just use the [`@dgraph(type: ...)`]({{< relref "directive-dgraph.md">}}) directive to maintain backward compatibility with the existing data. Depending on your use-case, you might find option 1 or 2 better for you. For example, if you