Giter Club home page Giter Club logo

dqlx's Introduction

dqlx

dqlx is a fully featured DGraph Schema and Query Builder for Go. It aims to simplify the interaction with the awesome Dgraph database allowing you to fluently compose any queries and mutations of any complexity. It also comes with a rich Schema builder to easily develop and maintain your Dgraph schema.

CircleCI Coverage Status Go Report Card

Status

The project is getting close to its first official release

Why?

The DGraph query language is awesome! it is really powerful, and you can achieve a lot with it. However, as you start trying to add dynamicity (like any other declarative query language) you soon starts fiddling with a lot strings concatenations and can quickly get messy.

dqlx tries to simplify the interaction with DGraph by helping to construct Queries and mutations with a fluent API.

Features

  • Schema Builder (Types, Predicates, Indexes)
  • Filtering - Connecting Filters (AND / OR)
  • Nested Selection / Filters
  • Functions
  • Pagination
  • Aggregation
  • Sorting
  • GroupBy
  • Multiple Query Block
  • Query Variables
  • Values Variables
  • Facets
  • Mutations

Documentation

You can find the documentation here: https://fenos.github.io/dqlx


Installation

go get github.com/fenos/dqlx

Quick Overview

func main() {
    // Connect to Dgraph cluster
    db, err := dqlx.Connect("localhost:9080")

    if err != nil {
        log.Fatal()
    }

    ctx := context.Background()

    var animals []map[string]interface{}

    // Query for animals
    _, err = db.
        QueryType("Animal").
        Select(`
            uid
            name
            species
            age
        `).
        Filter(
            dqlx.Eq{"species": "Cat"},
            dqlx.Lt{"age": 5},
        ).
        UnmarshalInto(&animals).
        Execute(ctx)

    if err != nil { panic(err) }

    println(fmt.Sprintf("The animals are: %v", animals))
}

Licence

MIT

dqlx's People

Contributors

aisbergg avatar allanglen avatar diegostamigni avatar droslean avatar easyas314159 avatar fenos avatar panakour avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

dqlx's Issues

dgraph performance

Inserting 10,000 pieces of data in dgraph is very slow, but inserting 10,000 pieces of data at one time is very fast. Can dqlx add the function of combining query & mutation to improve performance?

GODOC

@fenos Since there is no godoc, it is really hard to read the library. Are there any plans for creating documentation?

Mutation Response returns wrong data

Currently, the response of any mutation returns a map of uids and an empty JSON. This is 100% wrong for the following reasons:

  • The uids will be returned for some reason when dgraph won't generate the object because of an error that is never returned.
  • The Dgraph database returns also the objects that are being generated (based on the schema), but those objects are not included in the response.

Incorrect Example shown for Upserts

data := []map[string]interface{}{
    {
        "uid": "uid(v)",
        "email": "[email protected]",
        "name": "first name"
    },
}

userByEmailQuery := dqlx.Query(dqlx.EqFn("email", "[email protected]")).
    .Select(`
        v as uid
        name
    `)

resp, err := db.Mutation().
    Query(userByEmailQuery).
    Set(data).
    Execute(ctx)

The above example does not work, as userByEmailQuery is of type dqlx.QueryBuilder and Query() needs dqlx.DQLizer

Cascade directive

Hi,
I've not found any information about the @cascade directive in the library's documentation (I assume it's just not supported yet).

I was thinking about the "ugly" workaround:

  • Add @filter(@cascade) at the root level - run ToDQL func - replace string @filter(@cascade) with just @cascade - turn back to QueryBuilder (generally I wanted to update only query string, but I didn't find any solution for turning query, args, and error back into QueryBuilder)

Can you give me a solution on how to add @cascade for my query? It's crucial for one of my functions.

Also, it would be nice to be able to modify the query string more directly with function, which would allow adding custom parts to the query at the root level (next to filters etc.). For example, when Dgraph would release another part of the query, needed to be placed at the root level then it would be easy to implement that part without a specific function from the DQLX package (considering that there isn't a function meant to add that part)

Conditional Upsert not work

with git main branch(8ff4e72) code and dgraph verion 23.1.0.
Conditional Upsert not work

data := []map[string]interface{}{
{
"uid": "uid(v)",
"email": "[email protected]",
"name": "first name"
},
}

userByEmailQuery := dqlx.Query(dqlx.EqFn("email", "[email protected]")).
.Select(v as uid name)

condition := dqlx.Condition(dqlx.Eq("len(v)", "1"))

resp, err := db.Mutation().
Query(userByEmailQuery).
Condition(condition).
Set(data).
Execute(ctx)

but i user dgo api, it works

query = `

query {
user as var(func: eq(email, "[email protected]"))
}mu := &api.Mutation{ Cond: @if(eq(len(user), 1)), // Only mutate if "[email protected]" belongs to single user. SetNquads: []byte(uid(user) "first name" .`),
}
req := &api.Request{
Query: query,
Mutations: []*api.Mutation{mu},
CommitNow: true,
}

// Update email only if exactly one matching uid is found.
_, err = dg.NewTxn().Do(ctx, req)

This solves it, I don't know if it will introduce other problems

diff --git a/predicate.go b/predicate.go
index 96cd546..97c9031 100644
--- a/predicate.go
+++ b/predicate.go
@@ -221,22 +221,22 @@ func EscapePredicate(field string) string {
predicate, alias, directive = parsePredicate(predicate)

            if alias != "" {
  •                   alias = fmt.Sprintf("<%s>:", alias)
    
  •                   alias = fmt.Sprintf("%s:", alias)
              }
    
  •           return fmt.Sprintf("%s %s %s<%s>%s", varName, asKeyword, alias, predicate, directive)
    
  •           return fmt.Sprintf("%s %s %s%s%s", varName, asKeyword, alias, predicate, directive)
      }
    
      field, alias, directive = parsePredicate(field)
    
      if alias != "" {
    
  •           alias = fmt.Sprintf("<%s>:", alias)
    
  •           alias = fmt.Sprintf("%s:", alias)
      }
    
      if strings.HasPrefix(field, "expand(") {
              return fmt.Sprintf("%s%s%s", alias, field, directive)
      }
    
  •   return fmt.Sprintf("%s<%s>%s", alias, field, directive)
    
  •   return fmt.Sprintf("%s%s%s", alias, field, directive)
    

}

Issue with edgeAS

Hey everyone,

First thank you for this amazing repo. My issue is about EdgeAS;

	var output []map[string]interface{}
	_, err := r.Conn.QueryType("User").
		Filter(
			dqlx.UID(uid),
		).
		EdgeAs("total", "friendship", dqlx.Facets(dqlx.And{
			dqlx.GtFn("requested_at", util.BeginningOfDay().Unix()),
			dqlx.LtFn("requested_at", util.EndOfDay().Unix()),
		}), dqlx.Select("uid")).
		EdgeAs("to", "friendship", dqlx.UID(otherUSER), dqlx.Facets(dqlx.And{
			dqlx.GtFn("requested_at", util.BeginningOfWeek().Unix()),
			dqlx.LtFn("requested_at", util.EndOfWeek().Unix()),
		}), dqlx.Select("uid")).
		UnmarshalInto(&output).
		Execute(ctx)

	log.Print(output)

when I run it, I'm getting an error as

"rpc error: code = Unknown desc = line 1 column 35: Expected Left round brackets. Got: lex.Item [9] \"func\" at 1:35",

And the generated DQL is

query Rootquery($0:string, $1:int, $2:int, $3:int, $4:int, $5:string) { to as(func: type(<User>)) @filter(uid($0)) { <hey> @facets((gt(<requested_at>,$1) AND lt(<requested_at>,$2))) { <uid> } <hey> @facets((gt(<requested_at>,$3) AND lt(<requested_at>,$4))) @filter(uid($5)) { <uid> } } }
map[$0:0x57 $1:1662760800 $2:1662847199 $3:1662242400 $4:1662847199 $5:0x56]

anyone can help me ?

ERROR: result must be a pointer

Can someone help me understand this?

The following code generates the error result must be a pointer.

var data []map[string]interface{}

client.Query(dqlx.HasFn("name")).
		Filter(
                   dqlx.UID("0x12345"),
		).Select(`
		    name
		`).UnmarshalInto(data).Execute(ctx)

@fenos

Upsert is not working

Hi, thank you for your library,

I was trying to make an upsert block https://dgraph.io/docs/mutations/upsert-block/#example-of-uid-function and I see in your documentation: https://fenos.github.io/dqlx/docs/mutations/set#logical-upsert the way to do it. But there is a type error.

In your example you add a Query in the mutation like this:

resp, err := db.Mutation().
    Query(userByEmailQuery).
    Set(data).
    Execute(ctx)

but the query method has a dependency on an interface DQLizer which has the method signature: ToDQL() (query string, args []interface{}, err error)

Using the query builder in your example:

userByEmailQuery := dqlx.Query(dqlx.EqFn("email", "[email protected]")).
    .Select(`
        v as uid
        name
    `)

given us an instance of QueryBuilder which has the method ToDQL() (query string, args map[string]string, err error) that is not match to the DQLizer method:

Looking for maintainers

Unfortunately due to lack of time and passion for Dgraph i'm unable to maintain the project as i'd like to.
If any of you would like to be a maintainer of dqlx please comment below

schema index not work with 23.1.0

schema := db.Schema()
schema.Type("User", func(user *dqlx.TypeBuilder) {
	user.String("name").IndexTerm()
	user.String("phone")
})


err = schema.Alter(ctx, dqlx.WithDropAllSchema(true))
if err != nil {
	panic(err)
}

schema index not work.
get chema from https://play.dgraph.io/?local :
: string .
: string .

bugs

hi, Thank you for your library:

bugs:

  1. Upsert Condition bug
  2. Edge As bug
  3. Schema facts, count, not support
  4. instructions not support

When will the new version be released?

Logical Upsert example does not work

https://fenos.github.io/dqlx/docs/mutations/set

The example has a dot to much and does not work since the type does not fit

data := []map[string]interface{}{
    {
        "uid": "uid(v)",
        "email": "[email protected]",
        "name": "first name"
    },
}

userByEmailQuery := dqlx.Query(dqlx.EqFn("email", "[email protected]")).  
    .Select(` // There shouldn't be a Dot here
        v as uid
        name
    `)

resp, err := db.Mutation().
    Query(userByEmailQuery).  // Type does not implement 'DQLizer'
    Set(data).
    Execute(ctx)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.