prasinos' work memo

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

RELAX NG Compact Syntax

XML Schema を読み書きするのにホントーに飽き飽きしているのですが、Atom Syndication Format の定義などで使われている RELAX NG Compact Syntax のチュートリアルを読んでみました。以前、XSD に慣れるために XSD から BNF へのコンバータを作っていましたが、そのとき作りたかったものはこれだ、と思いました。
スポンサーサイト

XSLT プロセッサ

なんかすぐ忘れるので書いておこう。

XSLT 処理系はブラウザに入っているので、XML を HTML にするような変換であれば XML に <?xml-stylesheet href="xxx.xsl" type="text/xsl" ?> とか書いておけば自動的にレンダリングまでやってくれる。

そうじゃなくて、XML から別の XML を作るときは、たとえば ruby だったら nokogiri とかが使える。 オンラインリファレンスより:

require 'rubygems'
require 'nokogiri'
doc   = Nokogiri::XML(File.read(ARGV[0]))
xslt  = Nokogiri::XSLT(File.read(ARGV[1]))
puts xslt.transform(doc, ['key', 'value'])

ま、でも、 libxslt の xsltproc とかのほうがずっと動作が速いので、速度が問題であればこっちを使ったほうがいいだろう。

CQL

SRU/CQL をサポートする必要がある。 この CQL というクエリ言語はずいぶんおもしろい。

まず、任意識別子が連続する数は必ず1または3なのである。 どんな構文も index relation searchTerm を論理演算子で結びつけたものになっていて、 ひとつのばあいは cql.searverChoice = を省略したものとみなされるので結局3つだ。 だからつまらない数式の構文などにわずらわされる必要がない。

また、識別子は文字列と名前空間という URL で同定される。 で、実際に使うときには URL では長すぎるので dc. みたくプレフィックスで表現する。 まるで XML みたいだ。

INN に学ぶ(続)

承前。1週間も寝てしまって内向きの仕事に追われていたが、書こうと思ったこと。

INN でおもしろいと思ったのは、記事に内部的にひとつづつ token という id が振られていて、 記事を読もうとしたときは message-id から一度(grephistory(1)などにより) token (uuid くらいの数字列)を得て、 そこから (sm(1) などにより) 記事を取得するのである。

正直あまり細かくみたわけではないが、こうすることにより、記事本体の物理的保存形態(4つくらいから選べるようになっている)から記事の管理(配送とか、ニュースグループ分けとか、いろいろ)を独立させることができるようになる。

というわけで、どうせストリーム的なアクセスが多いなら、データファイルはシーケンシャル(INN の timecaf とか cnfs みたいなもの)にしておいて、それを扱うロジックからは抽象的なトークンだけを扱うようにするのがいいな、と思った。ファイル某の何バイト目から何バイト、とかいうのを生で書くとろくなことがない。

で、エキスパイヤする場合ちょっと迷いがある。たぶん、timecaf みたく時系列でファイルを集めて古いファイルから順に捨てていくのだが、そのとき大量のトークンが失効するわけだ。で、上位ロジックの DB でそのトークンを参照しているレコードは消していかないと、検索結果が実は参照不能とかなったりする。まあ数%くらいは許されるだろうけど、どんどん増えたらまずいから、エキスパイヤというイベントを契機にして上位DBの削除をトリガしなければならない。そのトークンリストはどこから得るんだろう? と、文字にしないで考えていて悩んでいたが、トークンと実体の対応は下位 DB に書くので、そこで SELECT (または DELETE) FROM token WHERE file = 'jan20.dat'; てな感じでやっつけてしまえばよい。

やっぱり書いてみるものだ。

INNに学ぶ

INN を運用してみたのはいいけいけんであった。

さっきの OAI の話、ストレージの構造が気になる。いまどきは BLOB でデロっと書き込んだほうが効率がいいのだろうか。ま、DB全体で1ギガいかないくらいならそれでもいいかもしれん。チャンチャン。

ま、論より run で書いてみて、遅くて泣いたら考えるということだろう。

インデックスはDB でなければならないが、ストリーム的なアクセスをされるものはシーケンシャルファイルであったほうがやりやすい。 日ギガ単位のデータフローとかだとそうだろうな。

展開しないが眠くなったので寝る。

メモ

あまり信頼できないソースから OAI-PMH でハーベスティングしたメタデータストリームに対して検索サービスを作りたい。

信頼できない、とは、たとえば内容が違うのに <fileIdentifier> が重複するものが大量に出てくるとか、同じ内容で id が異なるものが怒涛のように出てくるとか、とんちんかんな内容のものがどんどこ混入するといった事故を想定している。そういうことは自分もやるし備えも必要だ。

すると、OAI-PMH の結果を直接貯蔵する DB とは別に検索用の DB は別にもったほうがいい。 パターンマッチに基づくパッチあて操作なんかを挟み込むことができる。

OAI-PMH のプロバイダもやる必要があるが、contact 以外の人物が勝手にパッチをあてたレコードを第三者提供すると責任問題になるので、一次DBから直送すればよい。一次DBはスイッチに近い性格となるから、ストレージ管理としては容量指定で古いものから消していかなければならないだろう。あまり難しい判断をさせるべきではない。

どうせ検索のバージョンアップ時に DB 再構築とかするけど、そのときは OAI の DB から平行に別マシンが吸い上げつつ DB 再構築をやって、完成したら旧サーバとさしかえてしまえばよいからハッピーだ。

ところが困ったことに、古いレコードも更新されなければずっと生き続けるということがある。それでは一次DBから直近のレコードだけなめても生きているレコードセット全体を再現できないということになるので、OAIの受信ストリームは別に抜き出して、テラバイトディスクか何か安いところにぶちこんでおくしかないだろう。あるいは一次DBでエキスパイヤをやめてしまえばこの区別も不要となる。

当面はそのほうがいいかな。いずれは必要なレコードだけ取捨して再コンパイルする長期保存DBを作るんだろうけど。

二次DBの保存形式は、いかようでもよいが、オリジナル形式での出力を求められるとなると、おのずとオリジナル未改変版が必要になってしまう。そうすると実は二次DBが長期保存ということになってしまう。

いやそれは目が粗い。インデックスはどのみち必要なのだから、適宜消化吸収されたレコードとオリジナルの未改変バイト列の対がレコードの実態である。で、未改変のほうがアーカイブというところにあって、消化されたほうが別のところにあって必要なときだけアーカイブを参照するということになる。結局三角形の絵はかわらない。

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。