RethinkDB - how to get a single document by query?

290 views Asked by At

How can I get one document only by query in RethinkDB?

for an example, I want to get the document by this query below:

 let searchQuery = {
    name: 'rob'
 }

var cursor = await r.table('users').filter(searchQuery).run(connection)
  var user = await cursor.toArray()
  console.log(user)

Result:

[ { email: '[email protected]',
    id: '00e18124-714b-4298-aa34-5126ebda8828',
    name: 'rob' } ]

Filter method actually returns a list of users with the same name - 'rob'.

I want the result like get method:

r.table('posts').get('a9849eef-7176-4411-935b-79a6e3c56a74').run(conn, callback);

Result:

{ email: '[email protected]',
  id: '00e18124-714b-4298-aa34-5126ebda8828',
  name: 'rob' }

But this method only takes document id.

Any ideas?

1

There are 1 answers

0
Lyubomyr Shaydariv On BEST ANSWER

get (by id) fetches a single row selection by design, but filter is a streaming operation that processes multiple values (like arrays and streams). You might want to use nth that's designed to query for a stream/array element by its position, or its close alternative (). Here is an example:

.filter({ name: 'rob' })`

will return an array like

[{"email":"[email protected]","id":"230de013-5d6a-436e-a7e9-a891c01913e5","name":"rob"}]

But the following queries

.filter({ name: 'rob' }).nth(0)
.filter({ name: 'rob' })(0)

will both return

{"email":"[email protected]","id":"230de013-5d6a-436e-a7e9-a891c01913e5","name":"rob"}

Note that both also throw ReqlNonExistenceError: Index out of bounds: 0 in case if there are no rows found. However, you can easily fix it using the default operator:

.filter({ name: 'not-rob' }).nth(0).default(null)

Tested using RethinkDB data explorer with the "Raw view" tab active since both "Tree view" and "Table view" display single-element array as a single object. I'm almost sure the RethinkDB query engine is smart enough to make using nth(0) much more efficient rather than fetching the whole cursor to an array and taking the latter's first element in your code.