0

I have some steps saved in RethinkDB like this :

{
 date: "Sat Feb 06 2015 00:00:00 GMT+00:00",
 step: 1
},
{
 date: "Sat Feb 06 2015 11:11:11 GMT+00:00",
 step: 3
},
{
 date: "Sat Feb 06 2015 22:22:22 GMT+00:00",
 step: 2
}

I'd like to count the number of steps done in order 1, 2, 3.

So for this example, I'd like to get something like this :

{
 step_1: 1,
 step_2: 1,
 step_3: 0
}

I have seen a step 1, so step_1 is 1
I have seen a step 2, and have seen a step 1 before, so step_2 is 1
I have seen a step 3, but I haven't seen a step 2 before, so step_3 is 0

I've tried a lot of things but didn't find a way to do it and actually I'm not really sure it's possible with RethinkDB.
Any of you have an idea for me ?

Thanks,
Adrien

Adrien
  • 1
  • 2
  • There is a little ambiguity in your question, so to clarify: in your example, if you have another row `{ date: "Sat Feb 06 2015 23:23:23 GMT+00:00", step: 4 }`, should the result have `step_4: 0` or `step_4: 1`? – Tryneus Feb 06 '15 at 19:35
  • If their is this other row, the result will be `step_4: 0` because the step 3 wasn't completed. – Adrien Feb 09 '15 at 18:28

1 Answers1

1

As a preface: this really abuses the r.js term, and so is always going to be a bit slow. So this solution is not really great for production services. Unless someone comes up with a better answer (i.e.: all ReQL) it would be better to do this mostly client-side, possibly using a group and min to pre-digest some of this.

A couple of us really think that there is an answer, and mine uses reduce with a JavaScript function for the main bit. Unfortunately in working on this answer I found a bug that crashes our server, so for the moment my answer is slightly untested, and not recommended, but the in-progres version might give you the start of an answer:

r.table('alpha').reduce(r.js('''(
function(left, right) {
    var returnValue = [];
    var sources = [left, right];
    for (var i in sources) {
        var source = sources[i];
        if (source.date) {
            if (!returnValue[source.step] || returnValue[source.step] > source.date) {
                returnValue[source.step] = source.date;
            }
        } else {
            for (i in source) {
                if (!returnValue[i] || returnValue[i] > source(key)) {
                    returnValue[i] = source(key);
                }
            }
        }
    }
    return returnValue;
})''')).map(r.js('''(
function (row) {
    var allValid = true;
    var lastDate = 0;
    var returnValue = [];
    for (i in row) {
        var afterLast = row[i] && row[i] > lastDate && allValid;
        allValid = afterLast == true;
        returnValue.push(afterLast);
        lastDate = row[i];
    }
}
})''')).run()
larkost
  • 89
  • 3
  • Thank you so much for your reply larkost. I'll try that but as you said, I don't really like the idea to use JS for that. I'd like to make funnels on a database who grew up by 1M steps per day so I need something really fast. And I prefer to do it on the server side to dispatch it on the rethinkDB servers. So do it in ReQL would be the best I think but I'm not sure if it is possible. Again, thank you so much for this example :-) – Adrien Feb 09 '15 at 18:40