npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@dgraphium/core

v0.3.3

Published

Query builder for Dgraph database.

Downloads

11

Readme

Dgraphium Core (QueryBuilder) npm version

Query builder for Dgraph database.

Table of contents

Install

Install using npm:

npm install @dgraphium/core

or yarn:

yarn add @dgraphium/core

Projection

Projection is basically an edge definition. Separately it can be defined by: edge({...}) which is exported from @dgraphium/core.

To define projection for a query:

  query(...).project({ /* projection here */ })

For describing an edge, object is used. Object almost looks like the returned value.

Each key's value type in the projection object can be:

  • 1 | true: include field in a result.
    • if you pass type to containing edge/projection, key maps to field: ${capitalized type}.${key}
    • if type is undefined, key maps to field with same name: ${key}
  • 0 | false: don't include field in a result.
  • string: key will map to passed value. Key simply maps to it so the output will be: ${key}: ${value}
  • Edge: nested edge.
  • Ref: query/value reference.

Projection Merging

You can call query.project(...) multiple times on same query object.

By default projections will deeply merge. New keys will be added, existing keys will be overwritten.

For example:

query.project({ a: 1, c: { d: 1 } });
query.project({ b: 1, c: { d: 0, k: 1 } });
/* resulting projection: {
  a: 1,
  b: 1 ,
  c: { d: 0, k: 1 }
} */

You can do projection merging on Edge as well using: edge.merge({...}).


To overwrite projection, you can set overwrite to true:

query.project({ a: 1 });
query.project({ b: 1 }, true);
// resulting projection: { b: 1 }

In case of Edge: edge.merge({...}, true)

Operators

Operators/Functions can be imported from @dgraphium/core/operators.

Supported operators:

basic operators

| operator | description | |-----------|-----------------------------------------------| | type | search by Type | | has | find nodes which has field/edge/predicate | | uid | find by uid | | predUid | find by nested edge's uid |

simple comparison operators

| operator | description | |----------|--------------------------| | eq | equals | | lt | less than | | lte | less than or equal to | | gt | greater than | | gte | greater than or equal to |

text operators

| operator | description | |--------------|--------------------------------------------------------------------------------------------------| | regex | regex search | | match | fuzzy matching | | anyOfText | full-text search with stemming and stop words to find strings matching any of the given text | | allOfText | full-text search with stemming and stop words to find strings matching all of the given text | | anyOfTerms | matches strings that have any of the specified terms in any order; case insensitive. | | allOfTerms | matches strings that have all of the specified terms in any order; case insensitive. |

Connecting Operators

Note: connecting operators (LogicalOperators) can't be used in query.func(...).

they can be imported by:

import { and, or, not } from '@dgraphium/core/operators';

Filtering

Operators can be used in filtering queries or nested edges.

  • filtering queries:

    For example fetch users with age between 18 and 30: query().filter(and(gt('age', 18), lt('age', 30)))

  • filtering nested edges: For example fetch user's posts, which has more than 10 likes:

    query().projection({
      posts: edge().filter(gt('likes', 10)),
    });

Pagination

All pagination methods are available for queries as well as nested edges.

  • .first(first: number): count of nodes to fetch (same as limit).
  • .offset(offset: number): node offset or amount of nodes to skip.
  • .after(id: Uid): fetch nodes after the id.

you can also use

.withArgs(args: {
  first: number,
  offset: number,
  after: Uid,
})

Directives

Query and Edge directives:

  • cascade

Query only directives:

  • ignoreReflex

Those directives are available on edge or query as a function, e.g. edge.cascase().

Query Variables (refs)

Query variable (ref) can be created by calling ref(...path: string[]) method on query object. path argument is a path to a field.

Note: unlike DQL, you can define as many refs as you want. Unless you use it somewhere, it will not be defined in the resulting query.

Query refs can be used either in projection (in which case field will point to val(varName)), or in func/filtering.

Path does not exist in query projection

New field will be added to varQuery projection and ref will point to it.

Examples
const varQuery = query().func(gt('age', 10));
const postsQuery = query()
  .func(uid(varQuery.ref('posts')))
  .project({ text: 1 });

postsQuery.toString() outputs:

{
    var(func: gt(age, 10)) {
      posts: v1 as posts
    }

    q1(func: uid(v1)) {
      text: text
    }
}

Path exists in query projection

Ref will point to whatever is at the given path.

Examples
  • pointed field with filtering:
const varQuery = query()
  .func(gt('age', 10))
  .project({
    posts: edge().filter(regex('text', /mysql/))
  });
const postsQuery = query()
  .func(uid(varQuery.ref('posts')))
  .project({ text: 1 });

postsQuery.toString() outputs:

{
    var(func: gt(age, 10)) {
      posts: v1 as posts @filter(regexp(text, /mysql/)) {
      }
    }

    q1(func: uid(v1)) {
      text: text
    }
}
  • graphql type field:
const varQuery = query('user')
  .func(gt('age', 10))
  .project({
    posts: edge('post').filter(regex('text', /mysql/)),
  });
const postsQuery = query('post')
  .func(uid(varQuery.ref('posts')))
  .project({ text: 1 });

postsQuery.toString() outputs:

{
    var(func: gt(User.age, 10)) {
      posts: v1 as User.posts @filter(regexp(Post.text, /mysql/)) {
      }
    }

    q1(func: uid(v1)) {
      text: Post.text
    }
}

GraphQL Types

If you have GraphQL schema, when you deploy that schema to Dgraph database, each field gets prefixed by it's type.

for example:

type User {
    id: ID!
    name: String!
    age: Int!
    posts: [Post]
}

type Post {
  id: ID!
  text: String!
  replyCount: Int
}

results in following Dgraph schema:

type User {
  User.name
  User.age
  User.posts
}

type Post {
  Post.text
  Post.replyCount
}

User.name: string
User.age: int
User.posts: [uid]

so to query such data, you need to prefix each field with it's type:

{
  me(func: uid(0x2)) {
    id: uid
    name: User.name
    age: User.age
    posts: User.posts @filter(gt(Post.replyCount, 2)) {
      id: uid
      text: Post.text
      replyCount: Post.replyCount
    }
  }
}

to achieve exactly above written query with Dgraphium:

query('user') // <- type User
  .name('me')
  .func(uid('0x2'))
  .project({
    id: 1,
    name: 1,
    age: 1,
    posts: edge('post', { // <- type Post
        id: 1,
        text: 1,
        replyCount: 1,
      })
      .filter(gt('replyCount', 2)),
  })

Combine Queries

you can combine queries with:

import { combine } from '@dgraphium/core';

const combinedQuery = combine(
  query1,
  query2,
  ...
);

Note:

  • don't call build method on query before passing to combine function.
  • query names should be unique.

Running a Query

You can run query or group of queries with @dgraphium/client:

await dgraphClient.newTxn().query(meQuery); // params will be included

Note: you can name parameters by: param.name(paramName). For example: params.string('myStrValue').name('myParamName'). This is useful when you want to reuse query and override parameters:

for example:

await dgraphClient.newTxn().queryWithVars(
  queryWithParam,
  { '$myParamName': 'myStrValueNew' }
);

Demo

import { query, edge } from '@dgraphium/core';
import { uid, regex, gt, gte, lt, and, or } from '@dgraphium/core/operators';
const meQuery = query()
  .name('me')
  .func(uid('0x2', '0x3', '0x4'))
  .filter(and(
    or(
      regex('name', /zura/i),
      regex('name', /benashvili/i),
    ),
    gte('age', 15),
    lt('age', 25)
  ))
  .project({
    id: 1, // uid = id
    name: 1,
    age: 1,
    posts: edge({
        id: 1,
        text: 1,
      })
      .filter(gt('createdDate', new Date('2020-01-01')))
      .first(10),
  })
  .first(1)
  .build();

meQuery.toString() outputs (built query string):

{
  me(func: uid(0x2, 0x3, 0x4), first: 1) @filter((regexp(name, /zura/i) OR regexp(name, /benashvili/i)) AND ge(age, 15) AND lt(age, 25)) {
    id: uid
    name: name
    age: age
    posts: posts (first: 10) @filter(gt(createdDate, 2020-01-01T00:00:00.000Z)) {
      id: uid
      text: text
    }
  }
}

run query with @dgraphium/client:

await dgraphClient.newTxn().query(meQuery);

use GraphQL Variables(params) in query

import { query, edge, params } from '@dgraphium/core';
import { uid, regex, gt, gte, lt, and, or } from '@dgraphium/core/operators';

const meQuery = query()
  .name('me')
  .func(uid(params.uids('0x2', '0x3', '0x4')))
  .filter(and(
    or(
      regex('name', params.regex(/zura/i)),
      regex('name', params.regex(/benashvili/i)),
    ),
    gte('age', params.int(15)),
    lt('age', params.int(25))
  ))
  .project({
    id: 1, // uid = id
    name: 1,
    age: 1,
    posts: edge({
        id: 1,
        text: 1,
      })
      .filter(gt(
        'createdDate',
        params.date(new Date('2020-01-01'))
      ))
      .first(10),
  })
  .first(1)
  .build();

meQuery.toString() outputs (built query string):

query q($p2: string, $p1: string, $p3: string, $p4: string, $p5: int, $p6: int) {
  me(func: uid($p1), first: 1) @filter((regexp(name, $p3) OR regexp(name, $p4)) AND ge(age, $p5) AND lt(age, $p6)) {
    id: uid
    name: name
    age: age
    posts: posts (first: 10) @filter(gt(createdDate, $p2)) {
      id: uid
      text: text
    }
  }
}

run query with @dgraphium/client:

await dgraphClient.newTxn().query(meQuery); // params will be included