Dgraph Schema and Queries for Gru Admin Panel

This is the Dgraph Schema for Gru

# Question properties
<question-1> <markdown> "content of question in markdown format" .
<question-1> <positive-score> 5 .
<question-1> <negative-score> 2.5 .
 
# Tag Properties
<tag-id> <name> "String"

# Question <> Tag Relationship
<question-1> <question.tag> <tag-id> .
<tag-id> <tag.question> <question-1> .

# Option properties
<option-id> <markdown> "content of answer in markdown format"  .

# Question <> Option Relationship
<question-1> <question.option> <option-id> .
<question-1> <question.correct> <option-id> .
<option-id> <option.question> <question-1> .

# Quiz Properties
<quiz-id> <name> "name" .
<quiz-id> <duration> "Time String" .
<quiz-id> <start-date> "Start Date" .
<quiz-id> <end-date> "End Date" .

# Quiz <> Question Relationship
<quiz-id> <quiz.question> <question-1> .

# Candidate Properties
<candidate-1> <name> "Candidate name" .
<candidate-1> <email> "candidate email" .
<candidate-1> <authentication_token> "candidate authentication token".
<candidate-1> <ping> "some string" .

#Candidate <> Question Relationship
<candidate-1> <candidate.question> <question-1> .
<question-1> <question.candidate> <candidate-id> .

#Candidate <> Quiz Relationship
<candidate-1> <candidate.quiz> <quiz-id>
<quiz-id> <quiz.candidate> <candidate-1>

#Candidate <> Option Relationship
<candidate-1> <candidate.answer> <option-id> .
<option-id> <option.candidate> <candidate-id> .

I am writing APIs for storing Question/Tags/Quiz. For that UI will send JSON data to the server which will be stored using dgraph query in above schema. I have the latest dgraph binary, which generates UID automatically, really great.

This is the thread, @mrjn told me to create so that @core-devs can help me with dgraph queries. Right now I don’t need help with the queries, but if I face problem I’ll post it here. Your suggestions are welcomed.

2 Likes

That’s awesome @Rahul-Sagore. Would be great if you could create a Wiki page around it and update it as you make any changes.

2 Likes

Yeah, as @pawan mentioned, the idea is to create a wiki page. That’d be great because wiki is better designed for holding documents of lasting value. Discuss is for discussions.

1 Like

When the admin will add Question from UI, how will he add tags to the question? Will he enter random text, comma separated kind of? Or will select from already stored tags?

You can autocomplete the tags, or show all the tags, let the user click on them. Also, have a create new tag… Pretty standard right?

1 Like

Yeah it will be like, autocomplete, or he can create new tag if not exist. For this, UI will need all tags, so that it can search for available tags on Frontend code. Is there a way in dgraph to get all tags? since what I understand, you need a relationship or root node to fetch underlying data. But in this case tags are not associated with question, and we have to let user to do that, so we have to display what tags he can attach to question.

As was pointed out earlier, associate tags with a quiz(which can have an xid so that you know the starting node for the quiz). Then something like should work

quiz(_xid_: "backend") {
   tags {
      _uid_
      name
   }
}

@pawan According to schema, Quiz doesn’t have relationship with tags, instead tags are associated with Question.
If you are associating tags with Quiz, then again it is the same problem as associating tags with Question. If I can associate it with Quiz, then I can do it with Question also.

But this is the problem here , how will you associate tags with Quiz? When admin is creating Quiz, he can enter quiz name, quiz duration which are new entries, but tags are not necessarily new entry. We have to show autocomplete and suggests admin that these are the tags that are available, or else he can enter a new one if not exist.

Your dgraph query is correct, but you are assuming that tags are already associated with quiz (Which will not be the case, admin will have power to create new quiz, add new tags, add new question, separately).

So to suggest tags while creating a Quiz/Question, you have to sent all stored tags to the frontend. That’s why I asked before also that do we have something like “Select * from tags” kind of implementation.

How about attaching all questions to a root node? Then you can run this query:

{
  root (_xid_: root) {
    question @ignore {  // This would ignore the intermediate step in the final reply.
      question.tag {
        name
      }
    }
  }
}

FYI, @ashwin95r Some interesting usage of directives.

Btw, do we have a schema version that is current somewhere? It’s useful to refer to it to answer your questions. Otherwise, it’s just an aim in the dark.

1 Like

This is what we will need, a root node, which will not be associated to anything, but entities will attach itself to it. That is one solution. We need root node for Tag/Question/Quiz to get all particular entries.

@mrjn First message in this thread has schema mentioned.

I don’t think you need to attach it to everything. Just questions and quiz should be sufficient. As in the query above, tags can be achieved by traversing 2 edges out from root.

Sorry for late, but I have added a wiki page for schema: https://wiki.dgraph.io/Gru#Schema

3 Likes

Ah… this is awesome! Now we can refer to it when answering your questions. Also, modify it as we come up with questions. In fact, if you add the questions that you need to ask for the data, I can take a stab at the respective queries for them, and modify the schema to fit them.

1 Like

These are the queries that will be needed for the Gru Admin:

  1. Fetch All Unique tags (I have tried this, see the last note)
  2. Save Questions & Tags Properties, with relationship between them (DONE)
  3. Fetch All Unique Question. (DONE, by querying root node)
  4. Save Quiz Properties and associate questions to the Quiz. (DONE)

Other queries:

  1. Saving Admin and Candidate’s Information
  2. Assigning authentication token to the Candidate for the quiz

Queries for GRU’s candidate facing UI (Not admin UI).

  1. Authenticate candidate for the quiz.
  2. Fetch one question at a time when user starts the quiz (This can be done by the offset)
  3. Store Ping information for the candidate
  4. Store the answer submitted by the candidate.

For Unique Tags:
I was getting all the tags by querying root node of question, but it was returning array of object, not the unique tags

{
   me: [ 
      {
         "question.tag":[
            {"name":"tagnew"},
            {"name":"tagold"}
          ] 
      },
      {
        "question.tag":[
           {"name":"Some tag"},
           {"name":"tagnew"}
        ],
      },
   ]
}

Hey @Rahul-Sagore

Thanks for putting them down here. How about making a Postman collection and sharing it? So as I said earlier, we should try to complete the Admin UI for adding questions(with all their content including tags), modifying a question, list all questions etc. by Sunday. Basically CRUD on questions.

Regarding your doubt regarding all unique tags, how about we associate tags with the root as well while creating them for now. Then later when we have the functionality(@ignore directive) of getting you all unique tags associated with the questions, you can change the implementation a bit.

Yeah forgot to add Postman collection.
This is the link for the postman collection: https://drive.google.com/file/d/0BxtQPnyvB1xpVGx1NUsxWmxDd2c/view?usp=sharing

“Setting tags to root”, that’s what I asked before as well. We need to store entities to root node, if we want to query all particular entities.
I tried @ignore, then realised it is not implemented yet, because got error : “Invalid symbol @”. We can change implementation later, for now root will be fine for tags.

Code is currently messy, will cleanup things this weekend. Working on UI as well side by side.

Or the other way is to get the tags with their _uid_ as you mentioned above, and de-duplicating them on the frontend to get all the unique tags with their names. This way you don’t have to attach them to the root. Let’s actually do this, lets not associate tags with the root node. You can run a query like this

curl localhost:8080/query -XPOST -d $'{
 me(_xid_:root) {
  question {
   question.tag {
     _uid_
     name
   }
  }
 }
}'

and then figure out all the unique tags on the frontend.

Let’s decide all this and document the queries and mutations, you would be running for this on the Wiki so that we are all on the same page.

1 Like

Yeah I can find unique tags on frontend also. But it should be a feature in dgraph, we should not make users of dgraph to do such computation on frontend/backend.

For now we can do this in Frontend, then later on we just have to modify the query, rather then decoupling tags with root. Good to go.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.