Chanon
Chanon

Reputation: 393

In RethinkDB using multi indexes for tags, how to get items that match more than one tag?

Suppose I have a story table (with example data):

 story
 {id: 1, name: 'First Story', tags: ['plants', 'flowers', 'dog']}
 {id: 2, name: 'Second Story', tags: ['flowers', 'wedding']}
 {id: 3, name: 'Third Story', tags: ['plants', 'wedding']}

The story table has a multi index on the tags field.

I can get all stories that have the plants tag with:

 r.table('story').getAll('plants', {index: tags})

Now how would I get all stories that have both the plants and wedding tags in an effecient manner (hopefully utilizing the tags multi index)?

The use case requires user selectable filtering on an arbitrary number of arbitrary tags.

Upvotes: 3

Views: 658

Answers (1)

Etienne Laurin
Etienne Laurin

Reputation: 7184

Passing multiple arguments to getAll finds the documents that match either tag:

r.table('story').getAll('plants', 'wedding', {index: 'tags'})

A simple multi-index on tags cannot be used to match all tags. A query that doesn't use an index would look like:

r.table('story').filter(r.row('tags').contains('plants','wedding'))

It might be possible to create and use a multi-index on the powerset of tags:

r.table('story').indexCreate('tags-powerset', r.row('tags').do(powerset), {multi:true})
r.table('story').getAll(['plants', 'wedding'], {index: 'tags'})

Because of restrictions of ReQL and in the interest of efficiency, the powerset function may need to be approximated, for example as:

function(tags) {
  return tags.concatMap(function(a){
    tags.map(function(b){
      return [a,b] })})}

Upvotes: 3

Related Questions