2018年08月19日

言語処理100本ノックでPython入門 #65 - MongoDBの検索

  

今日は、言語処理100本ノック 2015の第7章・問題65を解きます。


■ 問題
65. MongoDBの検索
MongoDBのインタラクティブシェルを用いて,"Queen"というアーティストに関する情報を取得せよ.さらに,これと同様の処理を行うプログラムを実装せよ.
「MongoDBのインタラクティブシェルを用いて」という部分は省略、後半のプログラムを作成するほうだけ考えます。

■ Pythonのコード
import json
import pymongo
from bson.objectid import ObjectId

def ObjectIdToStr(o):
    if isinstance(o, ObjectId):
        return str(o)
    raise TypeError(repr(o) + " is not suported")

def find(name):
    client = pymongo.MongoClient('localhost', 27017)
    db = client['MusicBrainzDb']
    co = db['artists']
    return co.find({'name': name})

def printArtist(artist):
    print('')
    print(json.dumps(artist, indent=4, ensure_ascii=False, sort_keys=True, default=ObjectIdToStr))

def main():
    for d in find('Queen'):
        printArtist(d)

if __name__ == '__main__':
    main()

■ 簡単に説明


find メソッドを使うと、該当するデータを(複数ある場合はすべて)取得できます。この結果をforで回しています。

取得したデータはJSON形式です。これをdumpメソッドで文字列にして表示しています。この時、
json.dumps(d, indent=4, ensure_ascii=False, sort_keys=True, default=ObjectIdToStr)
と、パラメータでensure_ascii=False としないと、以下のように
    "aliases": [
        {
            "name": "\u5973\u738b",
            "sort_name": "\u5973\u738b"
        }
    ],
漢字部分が、"\u5973"といった形式でエンコードされてしまいます。

それと、ObjectId()は、そのままではdumpsできないので、default= で変換ルーチンを登録しています。 これをやらないと、以下の例外が発生してしまいます。
TypeError: Object of type 'ObjectId' is not JSON serializable

ちなみに、ObjectIdToStr関数の中で使っている repr()組み込み関数は、オブジェクトの印字可能な表現を含む文字列を返します。

■ 結果
{
    "_id": "5b73dc59b520d9c8477aafe2",
    "aliases": [
        {
            "name": "Queen",
            "sort_name": "Queen"
        }
    ],
    "area": "Japan",
    "ended": true,
    "gender": "Female",
    "gid": "420ca290-76c5-41af-999e-564d7c71f1a7",
    "id": 701492,
    "name": "Queen",
    "sort_name": "Queen",
    "tags": [
        {
            "count": 1,
            "value": "kamen rider w"
        },
        {
            "count": 1,
            "value": "related-akb48"
        }
    ],
    "type": "Character"
}

{
    "_id": "5b73dcd0b520d9c8477b768e",
    "aliases": [
        {
            "name": "女王",
            "sort_name": "女王"
        }
    ],
    "area": "United Kingdom",
    "begin": {
        "date": 27,
        "month": 6,
        "year": 1970
    },
    "ended": true,
    "gid": "0383dadf-2a4e-4d10-a46a-e9e041da8eb3",
    "id": 192,
    "name": "Queen",
    "rating": {
        "count": 24,
        "value": 92
    },
    "sort_name": "Queen",
    "tags": [
        {
            "count": 2,
            "value": "hard rock"
        },
        {
            "count": 1,
            "value": "70s"
        },
        {
            "count": 1,
            "value": "queen family"
        },
        {
            "count": 1,
            "value": "90s"
        },
        {
            "count": 1,
            "value": "80s"
        },
        {
            "count": 1,
            "value": "glam rock"
        },
        {
            "count": 4,
            "value": "british"
        },
        {
            "count": 1,
            "value": "english"
        },
        {
            "count": 2,
            "value": "uk"
        },
        {
            "count": 1,
            "value": "pop/rock"
        },
        {
            "count": 1,
            "value": "pop-rock"
        },
        {
            "count": 1,
            "value": "britannique"
        },
        {
            "count": 1,
            "value": "classic pop and rock"
        },
        {
            "count": 1,
            "value": "queen"
        },
        {
            "count": 1,
            "value": "united kingdom"
        },
        {
            "count": 1,
            "value": "langham 1 studio bbc"
        },
        {
            "count": 1,
            "value": "kind of magic"
        },
        {
            "count": 1,
            "value": "band"
        },
        {
            "count": 6,
            "value": "rock"
        },
        {
            "count": 1,
            "value": "platinum"
        }
    ],
    "type": "Group"
}

{
    "_id": "5b73de48b520d9c8477d30e6",
    "ended": true,
    "gid": "5eecaf18-02ec-47af-a4f2-7831db373419",
    "id": 992994,
    "name": "Queen",
    "sort_name": "Queen"
}