Solrのjoinとblock joinについて
MySQLの場合
regions
id | name |
---|---|
1 | US |
2 | ASIA |
products
id | name | brand_id_s |
---|---|---|
1 | iPhone | 1 |
2 | iPad | 1 |
3 | Galaxy S3 | 2 |
4 | Galaxy Note | 2 |
5 | one X | 3 |
brands
id | name | region_id_s |
---|---|---|
1 | Apple | 1 |
2 | Samsung | 2 |
3 | HTC | 2 |
products.name が iPad の brands を検索
JOINでこんなかんじ
mysql> SELECT brands.* FROM brands -> INNER JOIN products ON brands.id=products.brand_id_s -> WHERE products.name="iPad"; +------+-------+-------------+ | id | name | region_id_s | +------+-------+-------------+ | 1 | Apple | 1 | +------+-------+-------------+ 1 row in set (0.00 sec) mysql>
products.name が iPad の brands がある region を検索
もうちょい複雑なJOINでこんなかんじ
mysql> SELECT regions.* FROM regions -> INNER JOIN brands ON regions.id=brands.region_id_s -> INNER JOIN products ON brands.id=products.brand_id_s -> WHERE products.name="iPad"; +------+------+ | id | name | +------+------+ | 1 | US | +------+------+ 1 row in set (0.00 sec) mysql>
ここまでは普通です。とは言ってもSQLを普段書かないので、すぐにJOINでこんがらがります。
Solr の JOIN(block joinではない)の場合
brands
id | name |
---|---|
1 | Apple |
2 | Samsung |
3 | HTC |
※ brands に resion_id_s がないのは使わないので付け忘れてました
products
id | name | brand_id_s |
---|---|---|
1 | iPhone | 1 |
2 | iPad | 1 |
3 | Galaxy S3 | 2 |
4 | Galaxy Note | 2 |
5 | one X | 3 |
ただし、それぞれのフィールドごとに_versionが付く
products.name が iPad の brands を検索
/solr/brands/select?q=:&fq={!join from=brand_id_s to=id fromIndex=products}name:iPad
<?xml version="1.0" encoding="UTF-8"?> <response> <lst name="responseHeader"> <int name="status">0</int> <int name="QTime">1</int> <lst name="params"> <str name="indent">true</str> <str name="q">*:*</str> <str name="_">1404925101638</str> <str name="wt">xml</str> <str name="fq">{!join from=brand_id_s to=id fromIndex=products}name:iPad</str> </lst> </lst> <result name="response" numFound="1" start="0"> <doc> <str name="id">1</str> <str name="name">Apple</str> <long name="_version_">1473164065209581568</long></doc> </result> </response>
products.name が iPad の brands がある region を検索
3つ以上のjoinはできない
Solr の BLOCK JOIN の場合
blocks (brandsとproductsをJOINすることを前提として作成)
parents を持つものにのみ _version が付く (区切りがブロック単位)
id | name | type_s |
---|---|---|
1 | Apple | parents |
1 | iPhone | |
2 | iPad |
id | name | type_s |
---|---|---|
2 | Samsung | parents |
3 | Galaxy S3 | |
4 | Galaxy Note |
id | name | type_s |
---|---|---|
3 | HTC | parents |
5 | one X |
products.name が iPad の brands を検索
(iPadのparentsを検索)
/solr/blocks/select?q=:&fq={!parent which=type_s:parent}+name:iPad
<?xml version="1.0" encoding="UTF-8"?> <response> <lst name="responseHeader"> <int name="status">0</int> <int name="QTime">1</int> <lst name="params"> <str name="indent">true</str> <str name="q">*:*</str> <str name="_">1404923918712</str> <str name="wt">xml</str> <str name="fq">{!parent which=type_s:parent}+name:iPad</str> </lst> </lst> <result name="response" numFound="1" start="0"> <doc> <str name="id">1</str> <str name="type_s">parent</str> <str name="name">Apple</str> <long name="_version_">1473164315527741440</long></doc> </result> </response>
wblocks (brandsとproductsとregionsをJOINすることを前提として作成)
grand_parents を持つものにのみ _version が付く (区切りがブロック単位)
id | name | type_s |
---|---|---|
1 | US | grand_parents |
1 | Apple | parents |
1 | iPhone | |
2 | iPad |
id | name | type_s |
---|---|---|
2 | Asia | grand_parents |
2 | Samsung | parents |
3 | Galaxy S3 | |
4 | Galaxy Note | |
3 | HTC | parents |
5 | one X |
products.name が iPad の brands を検索
(iPadのparentsを検索) /solr/blocks/select?q=:&fq={!parent which=type_s:parent}+name:iPad
<?xml version="1.0" encoding="UTF-8"?> <response> <lst name="responseHeader"> <int name="status">0</int> <int name="QTime">0</int> <lst name="params"> <str name="indent">true</str> <str name="q">*:*</str> <str name="_">1404924377347</str> <str name="wt">xml</str> <str name="fq">{!parent which=type_s:parent}+name:iPad</str> </lst> </lst> <result name="response" numFound="1" start="0"> <doc> <str name="id">1</str> <str name="type_s">parent</str> <str name="name">Apple</str></doc> </result> </response>
products.name が iPad の brands がある region を検索
(iPadのgrand_parentsを検索)
/solr/wblocks/select?q=:&fq={!parent which=type_s:grand_parent}+name:iPad
<?xml version="1.0" encoding="UTF-8"?> <response> <lst name="responseHeader"> <int name="status">0</int> <int name="QTime">1</int> <lst name="params"> <str name="indent">true</str> <str name="q">*:*</str> <str name="_">1404924542233</str> <str name="wt">xml</str> <str name="fq">{!parent which=type_s:grand_parent}+name:iPad</str> </lst> </lst> <result name="response" numFound="1" start="0"> <doc> <str name="id">1</str> <str name="type_s">grand_parent</str> <str name="region_s">US</str> <long name="_version_">1473164347482046464</long></doc> </result> </response>
いがいとJOINってできるもんですね(白目)
この blockjoin って cloud datastore でできないかなあというのが本題です。 ちょっとだけ、joinについてまとめてみようと思ったらえらいことになってしまった。