Joins
This page explores the different joins possible with qjoin.
A join defines how a base collection and a join collection will be related together. It always applies between 2 collections. A qjoin query can consist of one or more joins.
Simple joins
To do a simple join, the base collection and the joining collection must share an attribute in common.
spacecrafts = [
{'name': 'Kepler', 'cospar_id': '2009-011A', 'satcat': 34380},
{'name': 'GRAIL (A)', 'cospar_id': '2011-046', 'satcat': 37801},
{'name': 'InSight', 'cospar_id': '2018-042a', 'satcat': 43457},
{'name': 'lucy', 'cospar_id': '2021-093A', 'satcat': 49328},
{'name': 'Psyche', 'cospar_id': None, 'satcat': None},
]
spacecrafts_mission_infos = [
{'name': 'Kepler', 'mission_type': 'Space telescope', 'launch_date':'2009-03-07T03:49Z', 'end_of_mission': '2018-11-15'},
{'name': 'GRAIL (A)', 'launch_date':'2011-09-10T13:08Z', 'end_of_mission': '2012-12-17'},
{'name': 'InSight', 'mission_type': 'Mars lander', 'launch_date':'2018-05-05T11:05Z', 'end_of_mission': '2022-12-21'},
{'name': 'lucy', 'mission_type': 'Multiple-flyby of asteroids', 'launch_date':'2021-10-16T09:34Z'},
]
global_space_crafts = qjoin.on(spacecrafts).join(spacecrafts_mission_infos, key='name').all()
for spacecraft, spacecraft_mission_infos in global_space_crafts:
print(spacecraft['name'])
Left right joins using simple key
If the join is done on different attributes between the base collection and the join collection, then a left-right join will be necessary.
spacecrafts = [
{'name': 'Kepler', 'cospar_id': '2009-011A', 'satcat': 34380},
{'name': 'GRAIL (A)', 'cospar_id': '2011-046', 'satcat': 37801},
{'name': 'InSight', 'cospar_id': '2018-042a', 'satcat': 43457},
{'name': 'lucy', 'cospar_id': '2021-093A', 'satcat': 49328},
{'name': 'Psyche', 'cospar_id': None, 'satcat': None},
]
spacecrafts_mission_infos = [
{'mission': 'Kepler', 'mission_type': 'Space telescope', 'launch_date':'2009-03-07T03:49Z', 'end_of_mission': '2018-11-15'},
{'mission': 'GRAIL (A)', 'launch_date':'2011-09-10T13:08Z', 'end_of_mission': '2012-12-17'},
{'mission': 'InSight', 'mission_type': 'Mars lander', 'launch_date':'2018-05-05T11:05Z', 'end_of_mission': '2022-12-21'},
{'mission': 'lucy', 'mission_type': 'Multiple-flyby of asteroids', 'launch_date':'2021-10-16T09:34Z'},
]
global_space_crafts = qjoin.on(spacecrafts) \
.join(spacecrafts_mission_infos, left='name', right='mission') \
.all()
for spacecraft, spacecraft_mission_infos in global_space_crafts:
print(spacecraft['name'])
Joins using artificial key
If it is necessary to transform the keys to be able to make a join between the base collection and the joining collection, then it will be necessary to make a join from an artificial key.
spacecrafts = [
{'name': 'Kepler', 'cospar_id': '2009-011A', 'satcat': 34380},
{'name': 'GRAIL (A)', 'cospar_id': '2011-046', 'satcat': 37801},
{'name': 'InSight', 'cospar_id': '2018-042a', 'satcat': 43457},
{'name': 'lucy', 'cospar_id': '2021-093A', 'satcat': 49328},
{'name': 'Psyche', 'cospar_id': None, 'satcat': None},
]
spacecrafts_mission_infos = [
{'mission': 'KEPLER', 'mission_type': 'Space telescope', 'launch_date':'2009-03-07T03:49Z', 'end_of_mission': '2018-11-15'},
{'mission': 'GRAIL (A)', 'launch_date':'2011-09-10T13:08Z', 'end_of_mission': '2012-12-17'},
{'mission': 'INSIGHT', 'mission_type': 'Mars lander', 'launch_date':'2018-05-05T11:05Z', 'end_of_mission': '2022-12-21'},
{'mission': 'LUCY', 'mission_type': 'Multiple-flyby of asteroids', 'launch_date':'2021-10-16T09:34Z'},
]
global_space_crafts = qjoin.on(spacecrafts) \
.join(spacecrafts_mission_infos, left=lambda l: l['name'].lower(), right=lambda l: l['mission'].lower()) \
.all()
for spacecraft, spacecraft_mission_infos in global_space_crafts:
print(spacecraft['name'])
Multiple join
Multiple joins with multiple join collections can be composed on a single qjoin query.
spacecrafts = [.join(countries, left='country', right='name')
.join(countries, left='birth_country', right='name')
.all()
{'name': 'Kepler', 'cospar_id': '2009-011A', 'satcat': 34380},
{'name': 'GRAIL (A)', 'cospar_id': '2011-046', 'satcat': 37801},
{'name': 'InSight', 'cospar_id': '2018-042a', 'satcat': 43457},
{'name': 'lucy', 'cospar_id': '2021-093A', 'satcat': 49328},
{'name': 'Psyche', 'cospar_id': None, 'satcat': None},
]
spacecrafts_mission_infos = [
{'mission': 'Kepler', 'mission_type': 'Space telescope', 'launch_date':'2009-03-07T03:49Z', 'end_of_mission': '2018-11-15'},
{'mission': 'GRAIL (A)', 'launch_date':'2011-09-10T13:08Z', 'end_of_mission': '2012-12-17'},
{'mission': 'InSight', 'mission_type': 'Mars lander', 'launch_date':'2018-05-05T11:05Z', 'end_of_mission': '2022-12-21'},
{'mission': 'lucy', 'mission_type': 'Multiple-flyby of asteroids', 'launch_date':'2021-10-16T09:34Z'},
]
spacecraft_properties = [
{'name': 'Kepler', 'dimension': (4.7, 2.7, None), 'power': 1100, 'launch_mass': 1052.4},
{'name': 'GRAIL (A)', 'launch_mass': 202.4},
{'name': 'InSight', 'dimension': (6, 1.56, 1), 'power': 600, 'launch_mass': 694},
{'name': 'lucy', 'dimension': (13, None, None), 'power': 504, 'launch_mass': 1550},
]
global_space_crafts = qjoin.on(spacecrafts) \
.join(spacecrafts_mission_infos, left='name', right='mission') \
.join(spacecraft_properties, key='name') \
.all()
for spacecraft, spacecraft_mission_infos, spacecraft_property in global_space_crafts:
print(spacecraft['name'])
Multiple join on the same join collection
Multiple joins on a single join collection can be composed on a single qjoin query.
persons = [
{'name': 'John', 'age': 25, 'country': 'USA', 'birth_country': 'USA'},
{'name': 'Paul', 'age': 18, 'country': 'UK', 'birth_country': 'USA'},
{'name': 'Ringo', 'age': 20, 'country': 'UK', 'birth_country': 'UK'},
{'name': 'George', 'age': 22, 'country': 'UK', 'birth_country': 'Japan'},
{'name': 'Yoko', 'age': 30, 'country': 'Japan', 'birth_country': 'Japan'},
]
countries = [
{'name': 'USA', 'continent': 'America'},
{'name': 'UK', 'continent': 'Europe'},
{'name': 'Japan', 'continent': 'Asia'},
]
persons_with_country_infos = qjoin.on(persons) \
.join(countries, left='country', right='name') \
.join(countries, left='birth_country', right='name') \
.all()
for person, country, birth_country in persons_with_country_infos:
print(person['name'])