0

I'm currently going through the rethinkdb python tutorial.

Currently, I have 4 superheroes. In the example below, heroes is an alias for r.db("python_tutorial").table("heroes").

In[45]: list(heroes.run())
Out[44]: 
[{u'appearances_count': 98,
  u'hero': u'Wolverine',
  u'id': u'28b6a53f-14c6-4a36-bb0b-45a6fb9c77c9',
  u'magazine_titles': [u'Amazing Spider-Man vs. Wolverine',
   u'Avengers',
   u'X-MEN Unlimited',
   u'Magneto War',
   u'Prime'],
  u'name': u"James 'Logan' Howlett"},
 {u'aka': [u'Magnus', u'Erik Lehnsherr', u'Lehnsherr'],
  u'appearances_count': 42,
  u'hero': u'Magneto',
  u'id': u'19274b39-f829-4daa-ba2b-24fd680e01c6',
  u'magazine_titles': [u'Alpha Flight', u'Avengers', u'Avengers West Coast'],
  u'name': u'Max Eisenhardt'},
 {u'appearances_count': 72,
  u'hero': u'Storm',
  u'id': u'69848f10-2f5a-48f4-8d87-c310b88f9487',
  u'magazine_titles': [u'Amazing Spider-Man vs. Wolverine',
   u'Excalibur',
   u'Fantastic Four',
   u'Iron Fist'],
  u'name': u'Ororo Monroe'},
 {u'appearances_count': 72,
  u'hero': u'Professor Xavier',
  u'id': u'22dd3ab1-60d6-4679-9c39-2ad7da6e48d0',
  u'magazine_titles': [u'Alpha Flight', u'Avengers', u'Bishop', u'Defenders'],
  u'name': u'Charles Francis Xavier'}]

What I would like to do is group heroes in accordance with the magazine titles they were in. So, I'm trying to build a query, that would give something like the following:

u'Prime'
{    u'name': u"James 'Logan' Howlett"}
u'Fantastic Four'
{    u'name': u'Ororo Monroe'}
u'Excalibur'
{    u'name': u'Ororo Monroe'}
u'Defenders'
{    u'name': u'Charles Francis Xavier'}
u'Magneto War'
{    u'name': u"James 'Logan' Howlett"}
u'Bishop'
{    u'name': u'Charles Francis Xavier'}
u'Avengers West Coast'
{    u'name': u'Max Eisenhardt'}
u'Amazing Spider-Man vs. Wolverine'
{    u'name': u"James 'Logan' Howlett"}
{    u'name': u'Ororo Monroe'}
u'X-MEN Unlimited'
{    u'name': u"James 'Logan' Howlett"}
u'Alpha Flight'
{    u'name': u'Charles Francis Xavier'}
{    u'name': u'Max Eisenhardt'}
u'Avengers'
{    u'name': u"James 'Logan' Howlett"}
{    u'name': u'Charles Francis Xavier'}
{    u'name': u'Max Eisenhardt'}
u'Iron Fist'
{    u'name': u'Ororo Monroe'}

I have managed to do this through two separate queries. Here is essentially what I did:

In[46]: titles = list(heroes.concat_map(lambda hero: hero["magazine_titles"]).distinct().run())
In[47]: titles
Out[46]: 
[u'Alpha Flight',
 u'Amazing Spider-Man vs. Wolverine',
 u'Avengers',
 u'Avengers West Coast',
 u'Bishop',
 u'Defenders',
 u'Excalibur',
 u'Fantastic Four',
 u'Iron Fist',
 u'Magneto War',
 u'Prime',
 u'X-MEN Unlimited']

The above gives me a list of all the titles. Then, I merely search the database to see if the the titles are in a hero's magazine_titles. Like so:

In[48]: from collections import defaultdict
In[49]: title_data = defaultdict(list)
In[57]: for title in titles:
...         title_data[title] = list(heroes.filter(lambda hero: hero["magazine_titles"].contains(title)).pluck("name").run())
In[59]: for title, heroes in title_data.items():
...     pprint(title)
...     pprint(heroes, indent=4)

However, I would like to do this in one query. And regarding said query, would it be more efficient than doing two separate queries like I did?

Games Brainiac
  • 80,178
  • 33
  • 141
  • 199

1 Answers1

2

The group command with multi should do what you want:

heroes.group('magazine_titles', multi=True)['name']
Etienne Laurin
  • 6,731
  • 2
  • 27
  • 31
  • Thank you so much! Is there a cookbook anywhere that I can use? Or any pre-created dataset that I can play around with that has complex data types? – Games Brainiac May 13 '15 at 15:01
  • I don't think that really exists, but you can use the `r.http` command to import data from public apis (like Reddit, for example). `r.db('DATABASE').table('reddit').insert(r.http('http://www.reddit.com/r/javascript.json')('data')('children').map(r.row('data')))` – Jorge Silva May 13 '15 at 18:48