今回から 第7章: データベース です。今回は JSON 形式のデータを読んで、Key-Value-Store (KVS) データベースを作りました。LevelDB を初めて使いました。
言語処理100本ノック #060
第7章: データベース
artist.json.gzは,オープンな音楽データベースMusicBrainzの中で,アーティストに関するものをJSON形式に変換し,gzip形式で圧縮したファイルである.このファイルには,1アーティストに関する情報が1行にJSON形式で格納されている.JSON形式の概要は以下の通りである.
フィールド 型 内容 例 id ユニーク識別子 整数 20660 gid グローバル識別子 文字列 "ecf9f3a3-35e9-4c58-acaa-e707fba45060" name アーティスト名 文字列 "Oasis" sort_name アーティスト名(辞書順整列用) 文字列 "Oasis" area 活動場所 文字列 "United Kingdom" aliases 別名 辞書オブジェクトのリスト aliases.name 別名 文字列 "オアシス" aliases.sort_name 別名(整列用) 文字列 "オアシス" begin 活動開始日 辞書 begin.year 活動開始年 整数 1991 begin.month 活動開始月 整数 begin.date 活動開始日 整数 end 活動終了日 辞書 end.year 活動終了年 整数 2009 end.month 活動終了月 整数 8 end.date 活動終了日 整数 28 tags タグ 辞書オブジェクトのリスト tags.count タグ付けされた回数 整数 1 tags.value タグ内容 文字列 "rock" rating レーティング 辞書オブジェクト rating.count レーティングの投票数 整数 13 rating.value レーティングの値(平均値) 整数 86 artist.json.gzのデータをKey-Value-Store (KVS) およびドキュメント志向型データベースに格納・検索することを考える.KVSとしては,LevelDB,Redis,KyotoCabinet等を用いよ.ドキュメント志向型データベースとして,MongoDBを採用したが,CouchDBやRethinkDB等を用いてもよい.
60. KVSの構築
Key-Value-Store (KVS) を用い,アーティスト名(name)から活動場所(area)を検索するためのデータベースを構築せよ.
LevelDB の準備
参考 👉 PythonでLevelDBを使ってみる(plyvel) - Qiiita
LevelDB と plyvel、msgpack-python をインストール
$ brew install leveldb $ pip install plyvel $ pip install msgpack-python
練習用に書いてみたコード
# study_plyvel.py import plyvel my_db = plyvel.DB('test.lbd', create_if_missing=True) import pickle import msgpack def study_pickle(): for key, value in my_db: my_db.delete(key) print('[using pickle]') for i in range(8): serialized1 = pickle.dumps(list(j for j in range(i))) my_db.put(('key'+str(i)).encode('utf-8'), serialized1) for key, value in my_db: print(key, '=>', pickle.loads(value)) def study_msgpack(): for key, value in my_db: my_db.delete(key) print('\n[using msgpack]') for i in range(8): serialized2 = msgpack.packb(list(j for j in reversed(range(i)))) my_db.put(('key'+str(i)).encode('utf-8'), serialized2) for key, value in my_db: print(key, '=>', msgpack.unpackb(value)) if __name__ == '__main__': study_pickle() study_msgpack() my_db.close()
解答
json を使うのは 100本ノック #020 でやったはずだったけど忘れてしまったので、 以前に書いたコードを見たらなんとなく使えた(思い出したとは言っていない)。 100本ノックは始めてから休み休みやっているので、もう2年も前なんやな。以前に比べて頻度が上がっているから良しとするか……。
# knock_060.py import gzip import json DATAFILE = './artist.json.gz' import plyvel name_area_db = plyvel.DB('artist_name_area.lbd', create_if_missing=True) def read_json(file): with gzip.open(file, 'rt') as datafile: for l in datafile: data_json = json.loads(l) if 'area' in data_json: yield (data_json['name'], data_json.get('area')) def make_name_area_db(file): for key, value in name_area_db: name_area_db.delete(key) for artist in list(read_json(file)): name_area_db.put(artist[0].encode('utf-8'), artist[1].encode('utf-8')) if __name__ == '__main__': make_name_area_db(DATAFILE) print(name_area_db.get('Avicii'.encode('utf-8')).decode('utf-8'))
↓ 出力
$ python knock_060.py Sweden