概要

校異源氏物語テキストDBに対する検索を行うAPIサーバの構築したので、備忘録です。

https://genji-api.aws.ldas.jp/

背景

以下のページで、『校異源氏物語』のテキストデータをTEI/XMLに準拠した形で公開しています。

https://kouigenjimonogatari.github.io/

このテキストデータをElasticsearchに登録し、コマごとの検索を可能にするAPIを作成します。

使い方

以下のURLで、OpenAPIおよびSwaggerを用いた使い方の説明ページにアクセスできます。

https://genji-api.aws.ldas.jp/

工夫点

検索語の展開

例えば以下のURLは、「夕顔」を検索キーワードとした例です。JSON:APIに準拠した入出力形式としています。

https://genji-api.aws.ldas.jp/search?q=夕顔&page[limit]=20&page[offset]=0&sort=page&filter[expandRepeatMarks]=true&filter[unifyKanjiKana]=true&filter[unifyHistoricalKana]=true&filter[unifyPhoneticChanges]=true&filter[unifyDakuon]=true&filter[vol_str]=04 夕顔

この時、以下のような結果が返却されます。入力したキーワード「夕顔」に対して、バリエーションを生成し、これらに基づく検索を行います。

{}""}dmae""]"}"}"""""}ttqt,t,f,slotaaaur"""""""""r"""""i""""""oifog"}""eaaeuuuuleuuuuvrmftgv::rnnxnnnntxnnnnotisaro"""]ys"spiiiiepiiiil"teleldsb[{"f,""""faffffraffff_:"t"g_ouu{}]:o"""",,,onyyyysnyyyys:":ascmc,r,,,,rdKHPD"dKHPDt":tt__k"""mmRaiha:Raiharp27ircoekdeOensokensok"a00,o"otteodppjtnu{pjtnu:g,,n:uhsyc"Qteioeoeioeoesne""_,uiaKrtnaKrtn"""{tr::ceotaii"taii"0,:__ornMncc:Mncc:4ed["uisaaaCaaaC{ro0ne"r"lhtr"lhtrc4ts:k:Kark:Karo_""sanusanu"rc::{"tnge"tnge_o:rae:rae,uu"7[u"su"spn,te:"te:"ptr,:r,:e"ututr:ertert_,ur,urb0eueuo,,e,eu,,nd":0,

その結果、本文中に登場する「ゆふかほ」「夕かほ」「夕顔」を一度に検索することができます。

この検索キーワードの展開については、検索オプションをON/OFFを切り替えられるようにしています。詳細は、上述したSwagger UIでご確認ください。

Elasticsearchには、以下のようなOR検索を投げています。

{}"}"""]q,sfsu"}iro{}ebzorro"]""}emt"}yos,mf"""p"lh{}{}{}{}{}{}{}{}{}ii"}:::a":"o,,,,,,,,nltgo:u"}"}"}"}"}"}"}"}"}ite"]20[er{lwwwwwwwwwmerv0,"d{di"i"i"i"i"i"i"i"i"urmo",:e"lololololololololom"sl0r:drdrdrdrdrdrdrdrdr_:"_4{"cicicicicicicicicis:s:[agagagagagagagagagh{triririririririririo{r"dndndndndndndndndnu""a"a"a"a"a"a"a"a"a"al:s:l:l:l:l:l:l:l:l:ldc__________["{t{t{t{t{t{t{t{t{tmeeeeeeeeeaxxxxxxxxxttttttttttc_________hlllllllll"iiiiiiiii:nnnnnnnnneeeeeeeee1sssssssss,.........kkkkkkkkkeeeeeeeeeyyyyyyyyywwwwwwwwwooooooooorrrrrrrrrddddddddd""""""""":::::::::"""""""""**********"********""""""""

変換に使用しているルールは以下で確認することができます。

https://genji-api.aws.ldas.jp/normalization/rules

{}"}"}d,ma""}e""ttatvlayt"}"}"}"}aea"ptr,s,o,d"rs:eru"}"}"}"}"}t""""""p""""e""""":st"ilh,d,k,k,pahdkkpttuuuushdkkpiU{:bei"""""""""""a""""""""""""""""""""""""""""""""""""""""""""""""""a""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""a"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""h""""""""""""""""""tiaaahoinnnnciaaah{opusskn宿殿nossknnotoiiiirsknnond"t"t"""""""u""""""""""""""""""""""""""""""""""""""""""""""""""j""""""""""""""an"""""""""""""""""""tujananffffitujan"ane:o:::::::""""o::::::::::::::::::::::::::::::::::::::::::::::::::i"""""":""""""""""""""::"""""""""""":""""""""""""":::::"""""""""""::::""""":"""""""""K"""""""""e:::::::::::::::::::ooiKelsyyyypooiKe:tosr::::nK:::::""::"::::::::::::::::::":"""::::::::::::::::::":::::::""":"::::::::::::::::::a"":""""""""":"::""""::::""":trnKatR"HDKPtrnKater"{i""""""""""""""""""""""""""""""""""""""""""""""""""""""""""a::":""::::":"""""::::"""""n"""":::":""""::":""::"":"""":""""""""""":"::""::":""::""""i""""""""""""""""""{iRaniu:iaahii"ani"dm:c"""":n""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""j::::"""":::::":::"":::::::":::":::::::"""":::"":""""""::"":"::"":ccunjclsknooc:njc1"aa"""""""""""""""""""""""""""""""""""""""""""""""""""""""""a""""""""""""i""::"""":"":""""::"""":::"""":"""":::殿"""::::"C""""""""""""""""""alaiCe{tujnnaaiC.:l{l,,,,,,,""""{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"""""""""""""":::"""""""""::"""""""""""""""""""""""":::"""""""""""":h,,,,,,,,,,,,,,,,,leRRhsooie"l"""h0iK,,,:"""",",,,,,,,:"""""""""""宿:",",,":""",,,,,""""aKsuua"rnKt:K::a."za,","""",,""""","""""""""","","""",""""""",""""""""""""na"lln:i"aian02an{"""",,","""",,""",,","""",,"""""""""",,,"",,","",,""""{"""",,","""",,""",,","""",,""""""""""",,,"",",","",,""""gn:eegc:nc{n""g"0ta,,,,"",,,,,",,,",",,,,",,,",,,,,,,",,"","",,",",,"",,,,,"",,,,,",,,",",,,,",,,",,,,,,,",,"","",,",",,"",easse2aaCae,2i""",,,,",,,,,,,,,,,,""",,,,",,,,,,,,,,,,""R5""R7l""h""5o:,",",""""",",",""""":u0::u0K:a::-n,,,,"",,,,,,,"",,,l,lan0-{,,,,{e99en"g""6rs65sae-u",,""s2l:::("5e:Ts11""0"18",7,,,:""0(,,8:)4("2,.)("6"0,8Z"",)",)"

まとめ

不完全なところもあるかと思いますが、原文の表記揺れを吸収する仕組みを含めた検索用APIサーバの構築例について紹介しました。

参考になりましたら幸いです。