簡単な使い方
ブログのエントリを検索する例により使い方を説明します。
ここでの説明で使用するプログラムや設定ファイルはexampleディレクトリにありますので、あわせて参照ください。
文書のスキーマ定義
今回検索したいブログデータには以下の属性があります。
Luxでは、このような属性値を文書のスキーマとして定義する必要があります。
以下に定義例を示します。(blogs.document.conf)
field {
name: "title"
index {
indexing: true
index_to: "default"
}
display: true
}
field {
name: "url"
display: true
}
field {
name: "created_at"
display: true
attr_index {
indexing: true
type: STRING
size: 15
}
}
この文書定義ファイルでは、この文書には3つの属性(field) title、url、created_at があり、field {} でそれを表しています。
そして、各fieldの中に、それぞれの属性の詳細を書きます。
fieldの中には、name, index, display, attr_index などを書くことができ、それぞれの意味は以下の通りとなります。
- name: 属性値の名前(任意の文字列が可)
- index: インデックスの設定
- indexing: インデックスに追加するかどうか (true/false - デフォルトはfalse)
- index_to: この属性をどのインデックスに追加するか (任意の文字列を指定可 - デフォルトは"default")
- display: 表示用に使用するかどうか (true/false)
- attr_index: 属性インデックス(ソート用属性)の設定
- indexing: インデックスに追加するかどうか (true/false - デフォルトはfalse)
- type: この属性のタイプ (STRING/INT)
- size: この属性をサイズ
上記のスキーマでは、
- titleを"default"というインデックスに追加し、表示用にも使用する
- urlを表示用にのみ使用する
- created_atを表示用に使用し、文字列の属性インデックスに追加する
という定義になります。
文書の追加プログラム
上記で定義した文書スキーマをもとに、ブログのエントリデータを追加するプログラムを以下に示します。
04 | #include <boost/algorithm/string.hpp> |
08 | int main( int argc, char *argv[]) |
11 | std::cerr << argv[0] << " service" << std::endl; |
15 | Lux::Config::Document doc_config; |
16 | if (!Lux::DocumentConfigParser::parse(argv[1], doc_config)) { |
17 | std::cerr << "parse failed." << std::endl; |
22 | Lux::Engine engine(doc_config); |
23 | if (!engine.open(argv[1], Lux::DB_CREAT)) { |
24 | std::cerr << "opening engine failed" << std::endl; |
27 | Lux::Indexer indexer(engine); |
32 | while (getline(std::cin, line)) { |
34 | std::vector<std::string> items; |
35 | boost::split(items, line, boost::is_any_of( "^X" )); |
38 | if (items.size() != 4) { continue ; } |
41 | Lux::Document *doc = new Lux::Document(items[0]); |
42 | doc->add(Lux::Field::create( "created_at" , items[1])); |
43 | doc->add(Lux::Field::create( "url" , items[2])); |
44 | doc->add(Lux::Field::create( "title" , items[3])); |
48 | std::cout << ++i << ": " << items[0] << " indexed." << std::endl; |
索引構築の流れは、
- 15,16行目: 先ほど作成した文書の定義ファイルを読み込む
- 22,23行目: インデクサをインスタンス化
- 32-50行目: 各ブログエントリを追加するループ
- 41-47行目: 文書インスタンスを作成し、インデクサに追加することで、検索インデックスを更新
となります。
文書の検索プログラム
上記で定義した文書スキーマをもとに、ブログのエントリデータを検索するプログラムを以下に示します。
01 | #include <lux/search.h> |
07 | double gettimeofday_sec() |
10 | gettimeofday(&tv, NULL); |
11 | return tv.tv_sec + ( double )tv.tv_usec*1e-6; |
14 | int main( int argc, char *argv[]) |
17 | std::cerr << argv[0] << " service query" << std::endl; |
22 | t1 = gettimeofday_sec(); |
24 | Lux::Config::Document doc_config; |
25 | Lux::DocumentConfigParser::parse(argv[1], doc_config); |
28 | Lux::SortCondition scond(Lux::SORT_SCORE, Lux::DESC); |
30 | Lux::Paging paging(5); |
31 | Lux::Condition cond(scond, paging); |
34 | Lux::Engine engine(doc_config); |
35 | if (!engine.open(argv[1], Lux::DB_RDONLY)) { |
36 | std::cerr << "engine.open failed" << std::endl; |
39 | Lux::Searcher searcher(engine); |
41 | Lux::ResultSet rs = searcher.search(argv[2], cond); |
42 | t2 = gettimeofday_sec(); |
45 | std::cout << "total hits: " << rs.get_total_num() << std::endl; |
46 | std::cout << "base: " << rs.get_base() << std::endl; |
47 | std::cout << "num: " << rs.get_num() << std::endl; |
48 | std::cout << "time: " << t2 - t1 << std::endl; |
50 | while (rs.has_next()) { |
51 | Lux::Result r = rs.get_next(); |
52 | std::cout << "[id] " << r.get_id() << std::endl; |
53 | std::cout << "[title] " << r.get( "title" ) << std::endl; |
54 | std::cout << "[created_at] " << r.get( "created_at" ) << std::endl; |
55 | std::cout << "[url] " << r.get( "url" ) << std::endl; |
56 | std::cout << "score: " << r.get_score() << std::endl; |
57 | std::cout << std::endl; |
検索の流れは、
- 24,25行目: 索引構築の場合と同様に、文書の定義ファイルを読み込む
- 28-31行目: 検索条件を指定
- 34-39行目: サーチャをインスタンス化(読み取りのみで)
- 41行目: 検索処理(結果をResultSetで受け取る)
- 49-58行目: 結果の取得(ResultSetのイテレータから取り出し)
となります。
コンパイル & 実行
コンパイル
$ cd example
$ make
$ (index, search が作成される)
索引構築
$ ./index blogs < posts
$ (第一引数の"blogs"は設定ファイルの"xxx.document.conf" の部分を指定
検索
$ ./search blogs live
$ (結果)
ここまでがLuxでの検索までの流れになります。