Created
June 3, 2020 22:00
-
-
Save dpkirchner/f2448fef0d8b777a2413f415c4333036 to your computer and use it in GitHub Desktop.
dgraph, using groupby to report votes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
node recreate.js | |
node vote.js -p 'What do?' -c 'Candidate A' -v 'Voter B' | |
node vote.js -p 'What do?' -c 'Candidate A' -v 'Voter D' | |
node vote.js -p 'What do?' -c 'Candidate C' -v 'Voter D' | |
node vote.js -p 'What do?' -c 'Candidate C' -v 'Voter E' | |
node vote.js -p 'What do?' -c 'Candidate C' -v 'Voter A' | |
node votes.js -p 'What do?' | |
# output: | |
# Candidate A: 1 | |
# Candidate C: 3 | |
node vote.js -p 'What do?' -c 'Candidate B' -v 'Voter C' | |
node votes.js -p 'What do?' | |
# output: | |
# Candidate A: 1 | |
# Candidate B: 1 | |
# Candidate C: 3 | |
node vote.js -p 'What do?' -c 'Candidate A' -v 'Voter C' | |
node votes.js -p 'What do?' | |
# output: | |
# Candidate A: 2 | |
# Candidate C: 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "votedemo", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"dependencies": { | |
"commander": "^5.1.0", | |
"dgraph-js": "^20.3.0" | |
}, | |
"author": "", | |
"license": "ISC" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// (Re)creates the voting schema, wipes the data, and inserts hardcoded values | |
// | |
// node recreate.js | |
const dgraph = require('dgraph-js'); | |
const grpc = require('grpc'); | |
const schemas = ` | |
type Candidate { | |
candidate_name | |
} | |
candidate_name: string @index(exact) . | |
type Voter { | |
voter_name | |
} | |
voter_name: string @index(exact) . | |
type Vote { | |
vote_voter | |
vote_candidate | |
} | |
vote_voter: uid @reverse . | |
vote_candidate: uid @reverse . | |
type Poll { | |
poll_title | |
poll_votes | |
} | |
poll_title: string @index(exact) . | |
poll_votes: [uid] @count @reverse . | |
`; | |
const alter = async client => { | |
const op = new dgraph.Operation(); | |
op.setSchema(schemas); | |
await client.alter(op); | |
}; | |
const deleteAll = async client => { | |
const txn = client.newTxn(); | |
try { | |
const mu = new dgraph.Mutation(); | |
mu.setDelNquads(` | |
uid(candidate) * * . | |
uid(voter) * * . | |
uid(vote) * * . | |
uid(poll) * * . | |
`); | |
const req = new dgraph.Request(); | |
req.setCommitNow(true); | |
req.addMutations(mu); | |
req.setQuery(` | |
query { | |
candidate as var(func: type(Candidate)) | |
voter as var(func: type(Voter)) | |
vote as var(func: type(Vote)) | |
poll as var(func: type(Poll)) | |
} | |
`); | |
await txn.doRequest(req); | |
} finally { | |
txn.discard(); | |
} | |
}; | |
const createPoll = async client => { | |
const txn = client.newTxn(); | |
try { | |
const mu = new dgraph.Mutation(); | |
mu.setSetJson([{ | |
'dgraph.type': 'Poll', | |
poll_title: 'What do?', | |
uid: '_:poll', | |
}, ...['Voter A', 'Voter B', 'Voter C', 'Voter D', 'Voter E'].map(name => ({ | |
'dgraph.type': 'Voter', | |
voter_name: name, | |
})), ...['Candidate A', 'Candidate B', 'Candidate C'].map(name => ({ | |
'dgraph.type': 'Candidate', | |
candidate_name: name, | |
}))]); | |
const req = new dgraph.Request(); | |
req.setCommitNow(true); | |
req.addMutations(mu); | |
await txn.doRequest(req); | |
} finally { | |
txn.discard(); | |
} | |
}; | |
const main = async () => { | |
const stub = new dgraph.DgraphClientStub( | |
'127.0.0.1:9080', | |
grpc.credentials.createInsecure() | |
); | |
const client = new dgraph.DgraphClient(stub); | |
await alter(client); | |
await deleteAll(client); | |
await createPoll(client); | |
}; | |
main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Cast vote | |
// | |
// node vote.js -p 'What do?' -c 'Candidate C' -v 'Voter E' | |
const program = require('commander'); | |
const dgraph = require('dgraph-js'); | |
const grpc = require('grpc'); | |
const insertMutation = () => { | |
const mu = new dgraph.Mutation(); | |
mu.setSetJson([{ | |
'dgraph.type': 'Vote', | |
vote_voter: {uid: 'uid(voter)'}, | |
vote_candidate: {uid: 'uid(candidate)'}, | |
uid: '_:blank-0', | |
}, { | |
poll_votes: {uid: '_:blank-0'}, | |
uid: 'uid(poll)', | |
}]); | |
mu.setCond('@if(eq(len(voter), 1) and eq(len(candidate), 1) and eq(len(poll), 1) and eq(len(vote), 0))'); | |
return mu; | |
}; | |
const updateMutation = () => { | |
const mu = new dgraph.Mutation(); | |
mu.setSetJson({ | |
vote_voter: {uid: 'uid(voter)'}, | |
vote_candidate: {uid: 'uid(candidate)'}, | |
uid: 'uid(vote)', | |
}); | |
mu.setCond('@if(eq(len(voter), 1) and eq(len(candidate), 1) and eq(len(poll), 1) and eq(len(vote), 1))'); | |
return mu; | |
}; | |
const vote = async (client, params) => { | |
const {pollTitle, voterName, candidateName} = params; | |
const txn = client.newTxn(); | |
try { | |
const muInsert = insertMutation(); | |
const muUpdate = updateMutation(); | |
const req = new dgraph.Request(); | |
req.setCommitNow(true); | |
req.addMutations(muInsert); | |
req.addMutations(muUpdate); | |
req.setQuery(` | |
query query($voterName: string, $candidateName: string, $pollTitle: string) { | |
voter as var(func: eq(voter_name, $voterName)) @filter(type(Voter)) | |
candidate as var(func: eq(candidate_name, $candidateName)) @filter(type(Candidate)) | |
poll as var(func: eq(poll_title, $pollTitle)) @filter(type(Poll)) { | |
vote as poll_votes @cascade { | |
uid | |
vote_voter @filter(eq(voter_name, $voterName)) | |
} | |
} | |
} | |
`); | |
const varsMap = req.getVarsMap(); | |
varsMap.set('$voterName', voterName); | |
varsMap.set('$candidateName', candidateName); | |
varsMap.set('$pollTitle', pollTitle); | |
await txn.doRequest(req); | |
} finally { | |
txn.discard(); | |
} | |
}; | |
program. | |
requiredOption('-p, --poll <string>', 'Poll title'). | |
requiredOption('-c, --candidate <string>', 'Candidate name'). | |
requiredOption('-v, --voter <string>', 'Voter name'); | |
program.parse(process.argv); | |
const main = async (pollTitle, voterName, candidateName) => { | |
const stub = new dgraph.DgraphClientStub( | |
'127.0.0.1:9080', | |
grpc.credentials.createInsecure() | |
); | |
const client = new dgraph.DgraphClient(stub); | |
await vote(client, {pollTitle, voterName, candidateName}); | |
}; | |
main(program.poll, program.voter, program.candidate); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Report vote count | |
// | |
// node votes.js -p 'What do?' | |
const program = require('commander'); | |
const dgraph = require('dgraph-js'); | |
const grpc = require('grpc'); | |
const votes = async (client, pollTitle) => { | |
const txn = client.newTxn(); | |
try { | |
const query = ` | |
query query($pollTitle: string) { | |
result(func: eq(poll_title, $pollTitle)) @filter(type(Poll)) { | |
uid | |
poll_votes @groupby(vote_candidate) { | |
c: count(uid) | |
} | |
} | |
candidates(func: type(Candidate)) { | |
uid | |
candidate_name | |
} | |
} | |
`; | |
const queryResult = await txn.queryWithVars( | |
query, | |
{'$pollTitle': pollTitle} | |
); | |
const { | |
result, | |
candidates: candidatesIn, | |
} = queryResult.getJson(); | |
const candidates = {}; | |
candidatesIn.forEach(c => candidates[c.uid] = c.candidate_name); | |
result[0].poll_votes[0]['@groupby'].forEach(x => { | |
console.log(candidates[x.vote_candidate] + ': ' + x.c); | |
}); | |
} finally { | |
txn.discard(); | |
} | |
}; | |
program. | |
requiredOption('-p, --poll <string>', 'Poll title'); | |
program.parse(process.argv); | |
const main = async pollTitle => { | |
const stub = new dgraph.DgraphClientStub( | |
'127.0.0.1:9080', | |
grpc.credentials.createInsecure() | |
); | |
const client = new dgraph.DgraphClient(stub); | |
await votes(client, pollTitle); | |
}; | |
main(program.poll); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment