2014年10月7日火曜日

ソートすると1万件以降が表示できない

ORDER BY でソートをかけて、1万件目以降のデータを表示しようとすると、以下の様なエラーがでます。

ERROR : Virtuoso 22023 Error SR353: Sorted TOP clause specifies more then 10010 rows to sort. Only 10000 are allowed. Either decrease the offset and/or row count or use a scrollable cursor

LIMITとOFFSETの組み合わせで、1万1件目のみ表示にしても、とにかく1万件目以降を表示しようとするとダメです。

これを回避するには、virtuoso.iniの[Parameters]セクションにMaxTopSortedRowsというパラメータを追加しなさいと、いたるところで書かれています。

http://virtuoso.openlinksw.com/dataspace/doc/dav/wiki/Main/VirtSparqlCxmlFacetPivotBridge

でも、私の環境ではこのパラメータを認識せず、改善しませんでした。

さらに検索したところ、クエリを別にすればよいという裏ワザを見つけました。
これでうまくいきました。

https://github.com/mff-uk/DPUs/issues/78


具体的には、こんなかんじで、いつものSELECTはORDER BYまでにして、それを囲む感じで LIMITとOFFSET をつけます。

変更前
SELECT ?a ?b ?c WHERE {?a ?b ?c} ORDER BY ?a
LIMIT 10 OFFSET 10000

変更後
SELECT * WHERE {
  SELECT ?a ?b ?c WHERE {?a ?b ?c} ORDER BY ?a
}
LIMIT 10 OFFSET 10000

これでうまくいきました。


2014年7月29日火曜日

グラフの操作

SPARQLにはグラフをまるごと操作する方法が用意されています。

  • CREATEオペレーションは、空のグラフをサポートしているストアに新しいグラフを作成します。
  • DROPオペレーションは、グラフとその内容のすべてを削除します。
  • COPYオペレーションは、別のグラフのコピーを含むようにグラフを修正します。
  • MOVEオペレーションは、あるグラフから別のグラフにすべてのデータを移動させます。
  • ADDオペレーションは、あるグラフのすべてのデータを別のグラフへと再作成させます。



ここに詳しく書いてます。
http://www.asahi-net.or.jp/~ax2s-kmtn/internet/rdf/REC-sparql11-update-20130321.html#graphManagement

2014年5月19日月曜日

Virtuoso 42000 Error

長いSPARQL文を投げると、下記のようなエラーが出る場合がある。

Virtuoso 42000 Error The estimated execution time 1498 (sec) exceeds the limit of 400 (sec).

日本語訳するとこうで、

ビルトーソ 42000 エラー 推定実行時間1498(秒)は、400(秒)の制限を超えています。

これはおそらく、
「このSPARQLはクソ難しいので実行すると1498秒もかかりそうだからやりたくないよ~」
といっているのだと思う。

virtuoso.ini の中に、MaxQueryCostEstimationTime という設定項目があるので、
そこの値を大きくしてあげれば、長いSPARQL文も実行できるようになる。

ちなみにデフォルトは 400 でした。
適当に4000にしてみました。

MaxQueryCostEstimationTime = 400   ; in seconds
  ↓
MaxQueryCostEstimationTime = 4000   ; in seconds




2014/08/20 追記
少々上げたぐらいではすぐに同じエラーにひっかかるので無制限にしてしまったほうが楽、とうことで、行自体をコメントアウトすると無制限になります。
 ;MaxQueryCostEstimationTime = 4000   ; in seconds


 下記のページ参考になりました。ありがとうございます。
http://wiki.lifesciencedb.jp/mw/index.php/BH12.12/SPARQLthon8/TogoGenome-Virtuoso7

2014年4月16日水曜日

よくつかうSPARQLサンプル集

とりあえずトリプルが何件入ってるか知りたい
SELECT count(*) WHERE { ?s ?p ?o }
 

とりあえずどんなトリプルが入っているか見たい
SELECT * WHERE { ?s ?p ?o } LIMIT 500

グラフ毎の件数を集計して見たい
SELECT ?g count(?g) WHERE {GRAPH ?g {?s ?p ?o}} GROUP BY ?g

あるグラフ配下のトリプルだけを見たい(何のグラフがあるかは一つ上↑のSPAQLで)
SELECT * WHERE { GRAPH <あるグラフ> {?s ?p ?o }}

aomoriが含まれるトリプルを探したい(主語から探す)
SELECT * { GRAPH ?g { ?s ?p ?o . FILTER( contains(str(?s),'aomori') ) }}

titleが含まれるトリプルを探したい(述語から探す)
SELECT * { GRAPH ?g { ?s ?p ?o . FILTER( contains(str(?p),'title') ) }}

青森県が含まれるトリプルを探したい(目的語から探す)
SELECT * { GRAPH ?g { ?s ?p ?o . FILTER( contains(str(?o),'青森県') ) }}

グラフ完全一致で探す
SELECT * { GRAPH <グラフ> {?s ?p ?o}}

主語完全一致で探す
SELECT * { GRAPH ?g {<主語> ?p ?o}}

述語完全一致で探す
SELECT * { GRAPH ?g {?s <述語> ?o}}

目的語完全一致で探す
SELECT * { GRAPH ?g {?s ?p '目的語'}}

目的語完全一致で探す(言語指定あり)
SELECT * { GRAPH ?g {?s ?p '目的語'@ja}}


以下のサイトでなどでお試しできます。(レスポンス悪いです)
http://dbpedia.org/sparql
http://ja.dbpedia.org/sparql


2014年3月27日木曜日

CentOS6.5(64bit)にVirtuoso7.1をインストールする

(#ではじまる行のコマンドを打ち込んでいきましょう。)

事前に、必要なパッケージをyumインストールします。
# yum install gmake autoconf automake libtool flex bison gperf openssl-devel readline-dev

ここからVirtuoso7.1のソースをもってきます。
http://sourceforge.net/projects/virtuoso/files/virtuoso/7.1.0/

解凍します。
# tar xvfz virtuoso-opensource-7.1.0.tar.gz

解凍したディレクトリに移動します。
# cd virtuoso-opensource-7.1.0

64bit版なのでそれなりの環境変数をセットしておきます。
ちなみにバージョン7には32bit版が無いです。

# CFLAGS="-O2 -m64"
# export CFLAGS

 こんふぃぐあーします。
# ./congifure

makeします。
# make

画面を見てると・・・警告がたくさん流れていきますが無視します。

root になります。
さっきのディレクトリに移動してから、make installします。
# mek install

インストール完了です。

Virtuosoの実行ファイルがあるところ
/usr/local/virtuoso-opensource/bin


VirtuosoのDBと設定ファイル(virtuoso.ini)があるところ
/usr/local/virtuoso-opensource/var/lib/virtuoso/db


起動するには root で以下の手順をふむ
# cd /usr/local/virtuoso-opensource/var/lib/virtuoso/db
# /usr/local/virtuoso-opensource/bin/virtuoso-t -df


コンダクター画面にいきます。
http://localhost:8890/conductor/

dba /dba で入れます。


完了です、いろいろいじってみましょー!


参考にしたブログ
http://d.hatena.ne.jp/watanabe162/20111020/1319117053
(こっちでは ./configureに--prefix=/usr/local/ つけてますね!こうするとパスを通さなくてもよくて楽なのかも! )

公式マニュアルはここ(英語)
http://virtuoso.openlinksw.com/dataspace/doc/dav/wiki/Main/VOSCentosNotes

2014年2月3日月曜日

ユーザのアクセス権限

ビルトーソのコンダクターにはユーザ管理画面がある。
[System Admin] -> [User Accounts]

ここで、[Create New Account]をクリックすると、新しくユーザを作ることができる。

このユーザのアクセス権限をいろいろ設定できるんだけど、実は、設定したいのはユーザごとに、RDFボキャブラリごとに、アクセス制限をしたいのだ。

いろいろいじってみたけど、テーブルの項目ごとまでアクセス権限が設定できるみたいで、それはそれですごいけど、望んでいたことはできなさそう。

ちなみに、
[System Admin] -> [User Accounts] -> [Grants]
からユーザをEditすると、テーブルごとのアクセス権限が設定できる。

そこからさらに、Columnsをクリックすると、テーブル項目ごとにアクセス権限が設定できる。

2014年1月22日水曜日

バックアップ&リストア

ビルトーソにはもろちん、バックアップ&リストア機能があります。

まずバックアップするには、

ビルトーソのコンダクターから、
System Admin -> Backup
にいきます。

Backup File Prefix
にバックアップファイル名の先頭につけたい文字を入力します。
とりあえず「unko」とでも入力しておきます。
(ただし後から変更できないので要注意です。)

Run Incremental Backup
ボタンをPUSHします。

すると、ビルトーソのdbディレクトリに、
xxxx1.bp
xxxx2.bp
というファイルができます。
これに全部のデータが入っています。

※dbディレクトリは人によって違うかもしれませんが、おそらくこのへんです。
/usr/local/var/lib/virtuoso/db


つづいて、リストアするには、

ビルトーソサーバを止めます。

dbディレクトリに移動します。
既存のdbファイルが存在しているとリカバリできないので、
どこかに移動しておきます。
# mv virtuoso-temp.db どこか
# mv virtuoso.db どこか

リストアコマンドを打ち込みます。
# virtuoso-t +restore-backup unko
※「unko」は上記で入力した「Backup File Prefix」です。

するとリカバリ処理が進みます。
イカのようにログが流れます。

                Wed Jan 22 2014
11:58:59 { Loading plugin 1: Type `plain', file `wikiv' in `/usr/local/lib/virtuoso/hosting'
11:58:59   WikiV version 0.6 from OpenLink Software
11:58:59   Support functions for WikiV collaboration tool
11:58:59   SUCCESS plugin 1: loaded from /usr/local/lib/virtuoso/hosting/wikiv.so }
11:58:59 { Loading plugin 2: Type `plain', file `mediawiki' in `/usr/local/lib/virtuoso/hosting'
11:58:59   MediaWiki version 0.1 from OpenLink Software
11:58:59   Support functions for MediaWiki collaboration tool
11:58:59   SUCCESS plugin 2: loaded from /usr/local/lib/virtuoso/hosting/mediawiki.so }
11:58:59 { Loading plugin 3: Type `plain', file `creolewiki' in `/usr/local/lib/virtuoso/hosting'
11:58:59   CreoleWiki version 0.1 from OpenLink Software
11:58:59   Support functions for CreoleWiki collaboration tool
11:58:59   SUCCESS plugin 3: loaded from /usr/local/lib/virtuoso/hosting/creolewiki.so }
11:58:59 OpenLink Virtuoso Universal Server
11:58:59 Version 06.01.3127-pthreads for Linux as of Dec 25 2013
11:58:59 uses parts of OpenSSL, PCRE, Html Tidy
11:58:59 Begin to restore with file prefix unko
11:58:59 --> Backup file # 1 [0xC8D5-0x0B-0x25]
11:59:07 --> Backup file # 2 [0xC8D5-0x0B-0x25]
12:00:11 End of restoring from backup, 12516 pages
12:00:11 Server exiting

リカバリ処理が止まったら、ビルトーソを起動します。
# virtuoso-t -df &

すると、元通り!

詳しくはここに書いてます。
http://docs.openlinksw.com/virtuoso/backup.html

2014年1月20日月曜日

ビルトーソとリッジレーサーの関係

PSVITA版のリッジレーサーには、
なんと、
VIRTUOSOという曲が入っています。


まさかゲームをやっててVIRTUOSOのスペルを見るとは思いもよりませんでした。
ビルトーソの影響力はすごいですね!

2014年1月9日木曜日

トリプルとかクアッドとか

SPARQLの世界では、トリプルとかクアッドとか言います。

スパークルでは、データを3つセットでDBに格納しまして、主語、述語、目的語をセットにしてトリプルといいます。

トリプル=Subject,Predicate,Object


さらに、グラフという、トリプルのまとまりとなる要素を付け加えて、クアッドといいます。

クアッド=Graph,Subject,Predicate,Object


CRAWL_LINK_EXTRACT 関数

WS.WS.SITEMAP_BB_PARSE から呼び出される関数です。
リンクを抽出して、次のクロール対象となるようにキュー登録します。
完全オリジナルです。
 
create procedure WS.WS.CRAWL_LINK_EXTRACT (
  in _content varchar,
  in _regexp varchar,
  in _host varchar,
  in _root varchar
)
{
dbg_obj_print('WS.WS.CRAWL_LINK_EXTRACT');
declare link varchar;
link := regexp_match(_regexp,_content,1);
while(link is not null) {
  declare url varchar;
  url := regexp_substr(_regexp,link,1);
  if (left(url,2) = '//') {
    url := null;
  }
  if (left(url,1) = '/') {
    url := 'http://' || _host || url;
  } else {
    url := null;
  }
  if (regexp_match('https?://'||_host,url) is null) {
    url := null;
  }
  if (url is not null) {
    insert soft VFS_QUEUE (VQ_HOST, VQ_TS, VQ_URL, VQ_STAT, VQ_ROOT, VQ_OTHER) values (_host, now(), url, 'waiting', _root, NULL);
    dbg_obj_print(url);
  }
  link := regexp_match(_regexp,_content,1);
}
}

CRAWL_REGEXP_TO_QUAD関数


WS.WS.SITEMAP_BB_PARSE から呼び出される関数です。
正規表現で項目を取り出して、SPARQLのDBに保存します。
完全オリジナル関数です。

create procedure WS.WS.CRAWL_REGEXP_TO_QUAD (
  in _content varchar,
  in _regexp varchar,
  in _graph varchar,
  in _subject varchar,
  in _predicate varchar
)
{
dbg_obj_print('WS.WS.CRAWL_REGEXP_TO_QUAD');
--parse
DECLARE value varchar;
value := regexp_substr(_regexp,_content,1);
dbg_obj_print(value);
--make sparql
declare sparql_str varchar;
sparql_str := sprintf('sparql insert in graph <%s> { <%s> <%s> "%s"}', _graph,_subject,_predicate,value);
--exec sparql
declare stat, msg varchar;
declare mdata, rset any;
exec (sparql_str, stat, msg, vector(), 1, mdata, rset);
}

Extract Function で項目抽出!!

Extract Functionで項目抽出してみます。
WS.WS.CRAWL_REGEXP_TO_QUAD関数と、
WS.WS.CRAWL_LINK_EXTRACT関数の中身は、
別記事に書いてあります。

create procedure WS.WS.SITEMAP_BB_PARSE (
  in _host varchar,
  in _url varchar,
  in _root varchar,
  inout _content varchar, 
  in _c_type varchar := null,
  in lev int := 0)
{
dbg_obj_print('sitemap_bb_parse by hodade v3');
dbg_obj_print('_host='||_host);
dbg_obj_print('_url='||_url);
dbg_obj_print('_root='||_root);
dbg_obj_print('_c_type='||_c_type);
dbg_obj_print('lev='||lev);
declare graph varchar;
graph := 'http://'||_host;
declare subject varchar;
subject := _url;
--#################
-- ボキャブラリ設定
--#################
WS.WS.CRAWL_REGEXP_TO_QUAD(
  _content,
  '<title>(.+?)</title>',
  graph,
  subject,
  'title'
);
WS.WS.CRAWL_REGEXP_TO_QUAD(
  _content,
  '<th width="100">.+?</th><td>(.+?)</td>',
  graph,
  subject,
  'address'
);
--##############
-- リンク抽出
--##############
WS.WS.CRAWL_LINK_EXTRACT(
  _content,
  '<a .*?href="(.+?/spot/.*?)".*?>',
  _host,
  _root
);
  commit work;
}