文書単位で検索する | python3Xのブログ

python3Xのブログ

ここでは40代、50代の方が日々の生活で役に立つ情報や私の趣味であるプログラム、Excelや科学に関する内容で投稿する予定です。

この内容は期間限定で公開しています

(まだ半ばほどですが、良い本に出合ったと思っています)

 

Solrを使って文書単位で検索を行います

また、次回はアノテーションで検索を行う予定です

solr.py
import json
import urllib.request as request
import urllib.parse as parse
# 使用するSolr の URL
solr_url = 'http://localhost:8983/solr'
opener = request.build_opener(request.ProxyHandler({}))
def load(collection, data):
    # Solr へデータを登録するリクエストを作成
    req = request.Request(
        url='{0}/{1}/update'.format(solr_url, collection),
        data=json.dumps(data).encode('utf-8'),
        headers={'content-type': 'application/json'})
       
    # データの登録を実行
    with opener.open(req) as res:
        # データの確認
        print(res.read().decode('utf-8'))
       
    # コミット
    url = '{0}/{1}/update?softCommit=true'.format(solr_url, collection)
    req = request.Request(url)
    with opener.open(req) as res:
        print(res.read().decode('utf-8'))
"""
①[単語A, 単語Aの同義語, 単語Aの同義語2], [単語B, 単語Bの同義語, 単語Bの同義語2]のイメージ
②検索クエリ:keywordsで指定された内容でcontent_txt_jaフィールドを検索
③dataのパラメータwt:受け取る検索結果の形式をjsonに指定
④Solrでの検索APIは/select、collection名はdoc⇒urlはこれを連結 doc/select
⑤③で作成したJSON形式のデータをdataとして指定
⑥検索の実行⇒検索結果をUTF-8のバイト列からUnicode文字列のstr型に変換
⇒JSON形式の文字列とみなし、dict型に変換したものを返す
"""  
     
def search(keywords, rows=100):        # ①
    query = ' AND '.join([                    # ②
        '(' + ' OR '.join(['content_txt_ja:"{0}"'.format(keyword)
            for keyword in group]) + ')'
        for group in keywords])
    data = {
        'q':        query,
        'wt':      'json',                        # ③
        'rows':   rows,
        'hl':       'on',
        'hl.fl':    'content_txt_ja',
    }
    # 検索リクエストの作成
    req = request.Request(
        url    = '{0}/doc/select'.format(solr_url),   # ④
        data  = parse.urlencode(data).encode('utf-8'),   # ⑤
    )
    # 検索リクエストの実行
    with opener.open(req) as res:
        return json.loads(res.read().decode('utf-8'))           # ⑥
"""
⑦ANDとORで連結:fl_keyword_pairs=[('names', [['sentence']])]
として渡されると
names:"senetence"のようなクエリが生成される
"""      
 
def search_annotation(fl_keyword_pairs, rows=100):       # ⑦
    query = ' AND '.join([
        '(' + ' OR '.join(['{0}:"{1}"'.format(fl, keyword)
            for keyword in group]) + ')'
        for fl, keywords in keyword_pairs
            for group in keywords])
    data = {
        'q':        query,
        'wt':      'json',
        'rows':   rows,
    }
    # 検索リクエストの作成
    req = request.Request(
        url    = '{0}/anno/select'.format(solr_url),
        data  = parse.urlencode(data).encode('utf-8'),
    )
    # 検索リクエストの実行
    with opener.open(req) as res:
        return json.loads(res.read().decode('utf-8'))
test.py
import json
import solr as indexer
"""
①検索を実行、その下は検索結果を表示
②入力したキーワードを含む部分を抜き出し
 ハイライトしたデータが入っている
③numFoundはヒットした数を表す
④responseのdocsに検索結果が入っている
"""
f = open('anno.txt', 'a')
if __name__ == '__main__':
    results = indexer.search(keywords=[['アメリカ'], ['大学']], rows=5)   # ①
   
    f.write('responseHeader' + '\n')
    print('responseHeader')
    f.write(str(json.dumps(results['responseHeader'], indent=4, ensure_ascii=False)) + '\n')
    print(json.dumps(results['responseHeader'],
                     indent=4, ensure_ascii=False), '\n\n')
   
    f.write('highlighting' + '\n')    # ②
    print('highlighting')
    f.write(str(json.dumps(results['highlighting'], indent=4, ensure_ascii=False)) + '\n')
    print(json.dumps(results['highlighting'],
                     indent=4, ensure_ascii=False), '\n\n')
   
    f.write('response' + '\n')
    print('response')
    f.write(str(results['response']['numFound']) + '\n')    # ③
    print(results['response']['numFound'])
    for row in results['response']['docs']:     # ④
        for fl, value in row.items():
            if fl == 'content_txt_ja':
                value = value[:300].replace('\n', ' ')
            f.write('{0}\t{1}'.format(fl, value) + '\n')
            print('{0}\t{1}'.format(fl, value))
        print()
f.close()
 
結果
responseHeader
{
    "status": 0,
    "QTime": 104,
    "params": {
        "q": "(content_txt_ja:\"アメリカ\") AND (content_txt_ja:\"大学\")",
        "hl": "on",
        "hl.fl": "content_txt_ja",
        "rows": "5",
        "wt": "json"
    }
}
highlighting
{
    "59": {
        "content_txt_ja": [
            "コスタリカ<__EOS__>\nコスタリカ共和国(コスタリカきょうわこく、スペイン語: República de Costa Rica)、通称コスタリカは、中央<em>アメリカ</em>南部に位置する共和制国家。北"
        ]
    },
    "178": {
        "content_txt_ja": [
            ":73.3%、女性:41.6%)である[13]。\n主な高等教育機関としては1862年設立の国立リベリア<em>大学</em>、<em>アメリカ</em>聖公会機関のカッティントン<em>大学</em>、工科<em>大学</em>のウィリアム・V・S・タブマン<em>大学</em>の<em>大学</em>3校"
        ]
    },
    "19": {
        "content_txt_ja": [
            "は、国民の圧倒的支持を集めて1951年4月に首相に就任した。モサッデグ首相はイギリス系アングロ・イラニアン石油会社から石油国有化を断行した(石油国有化運動)が、1953年8月19日に<em>アメリカ</em>中央情報局"
        ]
    },
    "162": {
        "content_txt_ja": [
            "メキシコ<__EOS__>\nメキシコ合衆国(メキシコがっしゅうこく、スペイン語: Estados Unidos Mexicanos)、通称メキシコは、北<em>アメリカ</em>南部に位置する連邦共和制国家。北"
        ]
    },
    "61": {
        "content_txt_ja": [
            "コロンビア<__EOS__>\nコロンビア共和国(コロンビアきょうわこく、スペイン語: República de Colombia)、通称コロンビアは、南<em>アメリカ</em>北西部に位置する共和制国家。東"
        ]
    }
}
response
87
id 59
doc_id_i 59
title_txt_ja コスタリカ
url_s https://ja.wikipedia.org/wiki/%E3%82%B3%E3%82%B9%E3%82%BF%E3%83%AA%E3%82%AB
content_txt_ja コスタリカ<__EOS__> コスタリカ共和国(コスタリカきょうわこく、スペイン語: República de Costa Rica)、通称コスタリカは、中央アメリカ南部に位置する共和制国家。北にニカラグア、南東にパナマと国境を接しており、南は太平洋、北はカリブ海に面している。首都はサンホセである。 1949年に常備軍を廃止する憲法を成立させ常備軍を持たない国となったが、同じく憲法によって非常時徴兵を規定している[2]。 チリやウルグアイと共にラテンアメリカで最も長い民主主義の伝統を持つ国であり、中央アメリカでは例外的に政治的に安定が続き、かつ経済状態も良好な「中米の楽園」と呼ばれるほどの国家
_version_ 1633676271107964928
id 178
doc_id_i 178
title_txt_ja リベリア
url_s https://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%99%E3%83%AA%E3%82%A2
content_txt_ja リベリア<__EOS__> リベリア共和国(リベリアきょうわこく)、通称リベリア(リビリとも言う)は、西アフリカに位置する共和制国家。北にギニア、西にシエラレオネ、東にコートジボワールと国境を接し、南は大西洋に面する。首都はモンロビア。 アメリカ合衆国で解放された黒人奴隷によって建国され、1847年に独立し、現在のアフリカの中ではエチオピアに次いで古い国である。しかし1989年から2003年にかけて断続的に2度も起きた内戦により、戦争一色の無秩序な国と化していた。現在もその影響で世界最貧国の一つとなっている。 目次<__EOS__> 国名[編集]<__EOS__> 正式名称は英語で、Repub
_version_ 1633676272831823872
id 19
doc_id_i 19
title_txt_ja イラン
url_s https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%A9%E3%83%B3
content_txt_ja イラン<__EOS__> イラン・イスラム共和国(イラン・イスラムきょうわこく、ペルシア語: جمهوری اسلامی ایران‎)、通称イランは、西アジア・中東のイスラム共和制国家。ペルシア、ペルシャともいう。人口は8千1百万人を超え、その多さは世界で18位である。1,648,195 平方キロメートル(km2 )の総面積は、中東で2番目に大きく、世界では17位である。北西にアルメニアとアゼルバイジャン、北にカスピ海、北東にトルクメニスタン、東にアフガニスタンとパキスタン、南にペルシア湾とオマーン湾、西にトルコ、イラク (クルディスタン) と境を接する。また、ペルシア湾を挟んでクウェート、
_version_ 1633676269979697152
id 162
doc_id_i 162
title_txt_ja メキシコ
url_s https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%AD%E3%82%B7%E3%82%B3
content_txt_ja メキシコ<__EOS__> メキシコ合衆国(メキシコがっしゅうこく、スペイン語: Estados Unidos Mexicanos)、通称メキシコは、北アメリカ南部に位置する連邦共和制国家。北にアメリカ合衆国と南東にグアテマラ、ベリーズと国境を接し、西は太平洋、東はメキシコ湾とカリブ海に面する。首都はメキシコシティ。メキシコの総人口は約1億3千万人(2016年時点)で、スペイン語圏においては最も人口の多い国で、GDPは中南米2位である[3]。 目次<__EOS__> 国名[編集]<__EOS__> 正式名称は、Estados Unidos Mexicanos( 発音、エスタドス・ウニドス・メヒ
_version_ 1633676272661954560
id 61
doc_id_i 61
title_txt_ja コロンビア
url_s https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%AD%E3%83%B3%E3%83%93%E3%82%A2
content_txt_ja コロンビア<__EOS__> コロンビア共和国(コロンビアきょうわこく、スペイン語: República de Colombia)、通称コロンビアは、南アメリカ北西部に位置する共和制国家。東にベネズエラ、南東にブラジル、南にペルー、南西にエクアドル、北西にパナマと国境を接しており、北はカリブ海、西は太平洋に面している。首都はボゴタ。 コロンビアの人口は、ブラジル、メキシコに続きラテンアメリカで第3位である。コーヒー、エメラルド、バラの産地である。 目次<__EOS__> 国名[編集]<__EOS__> 正式名称は、República de Colombia [reˈpuβlika ðe koˈ
_version_ 1633676271139422208