grahamjenson / ger_rethinkdb_esm Goto Github PK
View Code? Open in Web Editor NEWAn Event Store Manager for Good Enough Recommendations (GER) using RethinkDB
An Event Store Manager for Good Enough Recommendations (GER) using RethinkDB
The following query can be optimized by replacing the filter .ne() and use only indexes on the search.
So this query 40ms round-trip time
return r.table("default_events").getAll([var_3256("person"), var_3257("action")], {
index: "person_action"
}).filter(function(var_3258) {
return var_3258("thing").ne("a")
})
Will be better if we make use of a composed index person_action_thing and use between with union, leaving rightBound and leftBound open.
23ms round-trip time
r.db("hapiger_it").table("default_events").between(["p1", "view", r.minval], ["p1", "view", "a"], {
index: "person_action_thing",
rightBound: "open"
}).union(r.db("hapiger_it").table("default_events").between(["p1", "view", "a"], ["p1", "view", r.maxval], {
index: "person_action_thing",
leftBound: "open"
}))
Actual Query Profile
40ms round-trip time
[
{
"description": "Evaluating filter.",
"duration(ms)": 0.508081,
"sub_tasks": [
{
"description": "Evaluating get_all.",
"duration(ms)": 0.494773,
"sub_tasks": [
{
"description": "Evaluating table.",
"duration(ms)": 0.456685,
"sub_tasks": [
{
"description": "Evaluating db.",
"duration(ms)": 0.065233,
"sub_tasks": [
{
"description": "Evaluating datum.",
"duration(ms)": 0.000765,
"sub_tasks": []
}
]
},
{
"description": "Evaluating datum.",
"duration(ms)": 0.000254,
"sub_tasks": []
}
]
},
{
"description": "Evaluating datum.",
"duration(ms)": 0.000995,
"sub_tasks": []
},
{
"description": "Evaluating make_array.",
"duration(ms)": 0.00856,
"sub_tasks": [
{
"description": "Evaluating datum.",
"duration(ms)": 0.000378,
"sub_tasks": []
},
{
"description": "Evaluating elements in make_array.",
"mean_duration(ms)": 0.000615,
"n_samples": 1
}
]
}
]
},
{
"description": "Evaluating func.",
"duration(ms)": 0.001403,
"sub_tasks": []
}
]
},
{
"description": "Perform read.",
"duration(ms)": 0.713381,
"sub_tasks": [
{
"parallel_tasks": [
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.239102,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.079994,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.185966,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.02277,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.136859,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.024292,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.187845,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.021955,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.184639,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.022803,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.137011,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.024401,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.182047,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.022008,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.187839,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.022024,
"sub_tasks": []
}
]
}
]
]
}
]
}
]
Optimized Query Profile
23ms round-trip time
[
{
"description": "Evaluating filter.",
"duration(ms)": 0.086508,
"sub_tasks": [
{
"description": "Evaluating get_all.",
"duration(ms)": 0.080609,
"sub_tasks": [
{
"description": "Evaluating table.",
"duration(ms)": 0.068299,
"sub_tasks": [
{
"description": "Evaluating db.",
"duration(ms)": 0.056185,
"sub_tasks": [
{
"description": "Evaluating datum.",
"duration(ms)": 0.000439,
"sub_tasks": []
}
]
},
{
"description": "Evaluating datum.",
"duration(ms)": 0.000251,
"sub_tasks": []
}
]
},
{
"description": "Evaluating datum.",
"duration(ms)": 0.000224,
"sub_tasks": []
},
{
"description": "Evaluating make_array.",
"duration(ms)": 0.003561,
"sub_tasks": [
{
"description": "Evaluating datum.",
"duration(ms)": 0.000165,
"sub_tasks": []
},
{
"description": "Evaluating elements in make_array.",
"mean_duration(ms)": 0.000205,
"n_samples": 1
}
]
}
]
},
{
"description": "Evaluating func.",
"duration(ms)": 0.000915,
"sub_tasks": []
}
]
},
{
"description": "Perform read.",
"duration(ms)": 0.647678,
"sub_tasks": [
{
"parallel_tasks": [
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.17447,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.058303,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.108219,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.014863,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.183406,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.022122,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.179474,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.022076,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.106296,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.0147,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.106287,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.014628,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.174713,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.019082,
"sub_tasks": []
}
]
}
],
[
{
"description": "Perform read on shard.",
"duration(ms)": 0.174785,
"sub_tasks": [
{
"description": "Do range scan on secondary index.",
"duration(ms)": 0.019082,
"sub_tasks": []
}
]
}
]
]
}
]
}
]
implementation should cover the same as ps impl:
https://github.com/grahamjenson/ger/blob/master/lib/psql_esm.coffee
q = q.where(person: options.person) if options.person
q = q.whereIn('person', options.people) if options.people
q = q.where(action: options.action) if options.action
q = q.whereIn('action', options.actions) if options.actions
q = q.where(thing: options.thing) if options.thing
q = q.whereIn('thing', options.things) if options.things
Investigation:
I'm having a look into this queries, and it seems so far that they can be optimised on Rethinkdb level by adding queries with multiple indexes.
I'm playing with something to optimise the recommend query, this is my first try and it actually reduced the time spent by half:
Before:
r.db("hapiger").table("test_events").getAll("8kGdxrLI07Wz4LJq", {
index: "person"
}).filter(function(var_47) {
return var_47("created_at").le(r.ISO8601("2017-02-04T21:02:23.325Z"))
}).filter(function(var_48) {
return var_48("expires_at").ge(r.ISO8601("2017-02-04T21:02:23.000Z"))
}).filter(function(var_49) {
return r.expr(["view", "buy"]).contains(var_49("action"))
})
.orderBy(r.desc("created_at"))
.limit(5)
31ms round-trip time
After:
r.db("hapiger").table("test_events").between(
["8kGdxrLI07Wz4LJq", r.minval,r.minval,["view", "buy"]], ["8kGdxrLI07Wz4LJq", r.ISO8601("2017-02-05T21:02:23.325Z"),r.ISO8601("2017-02-05T21:02:23.000Z"),["view", "buy"]],
{index: 'person_created_at_expires_at_action'}).orderBy(r.desc("created_at")).limit(5)
15ms round-trip time
I will keep looking into this and submit a PR once I'm sure this will result in performance gains.
Cheers.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.