linkyndy
linkyndy

Reputation: 17900

Order by random in RethinkDB

I want to order documents randomly in RethinkDB. The reason for this is that I return n groups of documents and each group must appear in order in the results (so all documents belonging to a group should be placed together); and I need to randomly pick a document, belonging to the first group in the results (you don't know which is the first group in the results - the first ones could be empty, so no documents are retrieved for them).

The solution I found to this is to randomly order each of the groups before concat-ing to the result, then always pick the first document from the results (as it will be random). But I'm having a hard time ordering these groups randomly. Would appreciate any hint or even a better solution if there is one.

Upvotes: 3

Views: 576

Answers (4)

tomtom
tomtom

Reputation: 642

One simple solution would be to give each document a random number:

r.db('db').table('table')
  .merge(doc => ({
    random: r.random(1, 10)
  })        
  .orderBy('random')

Upvotes: 0

Obeyed
Obeyed

Reputation: 299

The accepted answer here should not be possible, as John mentioned the sorting function must be deterministic, which r.random() is not.

The r.sample() function could be used to return a random order of the elements:

If the sequence has less than the requested number of elements (i.e., calling sample(10) on a sequence with only five elements), sample will return the entire sequence in a random order.

So, count the number of elements you have, and set that number as the sample number, and you'll get a randomized response.

Example:

var res = r.db("population").table("europeans")
              .filter(function(row) { 
                  return row('age').gt(18) 
              });
var num = res.count();
res.sample(num)

Upvotes: 1

John
John

Reputation: 43

I'm not getting this to work. I tried to sort an table randomly and I'm getting the following error:

e: Sorting by a non-deterministic function is not supported in: r.db("db").table("table").orderBy(function(var_33) { return r.random(); })

Also I have read in the rethink documentation that this is not supported. This is from the rethinkdb orderBy documentation:

Sorting functions passed to orderBy must be deterministic. You cannot, for instance, order rows using the random command. Using a non-deterministic function with orderBy will raise a ReqlQueryLogicError.

Any suggestions on how to get this to work?

Upvotes: 0

Jorge Silva
Jorge Silva

Reputation: 4614

If you want to order a selection of documents randomly you can just use .orderBy and return a random number using r.random.

r.db('test').table('table')
  .orderBy(function (row) { return r.random(); })

If these document are in a group and you want to randomize them inside the group, you can just call orderBy after the group statement.

r.db('test').table('table')
  .groupBy('property')
  .orderBy(function (row) { return r.random(); })

If you want to randomize the order of the groups, you can just call orderBy after calling .ungroup

r.db('test').table('table')
  .groupBy('property')
  .ungroup()
  .orderBy(function (row) { return r.random(); })

Upvotes: 2

Related Questions