MongoDBに登録した住所を検索する

MongoDBに郵便番号と住所のデータを登録しました。
登録したデータに対し、郵便番号の検索を行いましたが、
今回は郵便番号の検索を試してみます。



MapとReduce



住所検索を行うには、Map・Reduceの機能を使用する必要があります。
CouchDBにもこの機能がありましたが、改めて復習してみます。

まず、サンプルとしてこんなデータを用意しました。


{u'lang': u'java', u'_id': ObjectId('4b3f6ba35179570368000000')}
{u'lang': u'perl', u'_id': ObjectId('4b3f6ba35179570368000001')}
{u'lang': u'python', u'_id': ObjectId('4b3f6ba35179570368000002')}
{u'lang': u'ruby', u'_id': ObjectId('4b3f6ba35179570368000003')}



langというキーで、プログラム言語の名前を保持しています。
このなかで、「r」が含まれる言語の検索を検討してみます。

まず、データをより分けるMap関数は以下のように考えてみました。


function () {
    if (this.lang.indexOf('r') != -1) {
        emit(this, 0);
    }
}



thisに解析中のデータが設定されます。
this.langには、javaやperlといった値が入りますので、その中に
rという文字列があれば、emit関数を呼んで、データを設定します。

emitの第二引数はReduce関数で使用されますが、今回Reduceの仕事は
無いので適当な値を設定しておきます。


Reduce関数は特に仕事は無いので、こんな感じにしてみました。


function (key, values) {
    return 0;
}



return 0するだけです。


プログラム全体ではこんな感じになりました。



#!/usr/bin/env python
# -*- coding:utf-8 -*-

from pymongo import Connection
from pymongo.code import Code

#コネクション作成
con = Connection('192.168.1.245', 27017)

#コネクションからtestデータベースを取得
db = con.test

#testデータベースからfooコレクションを取得
col = db.foo


map = Code("""
function () {
    if (this.lang.indexOf('r') != -1) {
        emit(this, 0);
    }
}
""")

reduce = Code("""
function (key, values) {
    return 0;
}
""")

#map,reduce共に設定する必要あり
result = col.map_reduce(map, reduce)

for data in result.find():
    #print data
    print data['_id']['lang']

con.disconnect()




実行してみると、狙い通りの動きです。


c:\>python sample.py
perl
ruby






住所検索への応用



動作概要をつかんだところで、郵便番号検索のサンプルです。
住所に「銀座」という文字列を含んでいる住所を検索します。


#!/usr/bin/env python
# -*- coding:utf-8 -*-

from pymongo import Connection
from pymongo.code import Code
import time

t1 = time.time()

#コネクション作成
con = Connection('192.168.1.245', 27017)

#コネクションからtestデータベースを取得
db = con.test

#testデータベースからyubinコレクションを取得
col = db.yubin


map = Code("""
function () {
    if (this.address.indexOf('銀座') != -1) {
        emit(this, 0);
    }
}
""")

reduce = Code("""
function (key, values) {
    return 0;
}
""")

#map,reduce共に設定する必要あり
result = col.map_reduce(map, reduce)

for data in result.find():
    #print data
    print data['_id']['zip_code'], data['_id']['address']


con.disconnect()

print time.time() - t1, 'sec'




実行結果です。


c:\>python sample.py
0691331 北海道夕張郡長沼町銀座
3220052 栃木県鹿沼市銀座
3600032 埼玉県熊谷市銀座
3670052 埼玉県本庄市銀座
1040061 東京都中央区銀座
9300991 富山県富山市新庄銀座
3940022 長野県岡谷市銀座
3940023 長野県岡谷市東銀座
3950031 長野県飯田市銀座
4240817 静岡県静岡市清水区銀座
4130013 静岡県熱海市銀座町
4140028 静岡県伊東市銀座元町
4750874 愛知県半田市銀座本町
4480845 愛知県刈谷市銀座
5220088 滋賀県彦根市銀座町
6128089 京都府京都市伏見区銀座町
7450032 山口県周南市銀座
7450033 山口県周南市みなみ銀座
7700916 徳島県徳島市銀座
8040076 福岡県北九州市戸畑区銀座
4.18700003624 sec




4秒程度かかりますが、まあこういう使い方をするデータベースじゃ
ないので、満足できる結果かと思います。







関連記事

コメント

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
https://symfo.web.fc2.com/

PR

検索フォーム

月別アーカイブ