簡単な使い方

ブログのエントリを検索する例により使い方を説明します。
ここでの説明で使用するプログラムや設定ファイルは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 などを書くことができ、それぞれの意味は以下の通りとなります。 上記のスキーマでは、 という定義になります。

文書の追加プログラム

上記で定義した文書スキーマをもとに、ブログのエントリデータを追加するプログラムを以下に示します。
01#include <lux/index.h>
02#include <iostream>
03#include <string>
04#include <boost/algorithm/string.hpp>
05  
06//エントリID^X投稿日^XURL^Xタイトル
07  
08int main(int argc, char *argv[])
09{
10  if (argc != 2) {
11      std::cerr << argv[0] << " service" << std::endl;
12      exit(1);
13  }
14  
15  Lux::Config::Document doc_config;
16  if (!Lux::DocumentConfigParser::parse(argv[1], doc_config)) {
17    std::cerr << "parse failed." << std::endl;
18    exit(1);
19  }
20  
21  // create indexer
22  Lux::Engine engine(doc_config);
23  if (!engine.open(argv[1], Lux::DB_CREAT)) {
24    std::cerr << "opening engine failed" << std::endl;
25    exit(-1);
26  }
27  Lux::Indexer indexer(engine);
28  
29  // for each document to be indexed
30  int i = 0;
31  std::string line;
32  while (getline(std::cin, line)) {
33  
34    std::vector<std::string> items;
35    boost::split(items, line, boost::is_any_of("^X"));
36  
37    // invalid input
38    if (items.size() != 4) { continue; }
39  
40    // create a document and add a title field object to it
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]));
45  
46    // add the created document to index
47    indexer.add(doc);
48    std::cout << ++i << ": " << items[0] << " indexed." << std::endl;
49  
50    delete doc;
51  }
52  
53  return 0;
54}
索引構築の流れは、 となります。

文書の検索プログラム

上記で定義した文書スキーマをもとに、ブログのエントリデータを検索するプログラムを以下に示します。
01#include <lux/search.h>
02#include <iostream>
03#include <string>
04#include <time.h>
05#include <sys/time.h>
06  
07double gettimeofday_sec()
08{
09  struct timeval tv;
10  gettimeofday(&tv, NULL);
11  return tv.tv_sec + (double)tv.tv_usec*1e-6;
12}
13  
14int main(int argc, char *argv[])
15{
16  if (argc < 3) {
17      std::cerr << argv[0] << " service query" << std::endl;
18      exit(1);
19  }
20  double t1, t2;
21  
22  t1 = gettimeofday_sec();
23  
24  Lux::Config::Document doc_config;
25  Lux::DocumentConfigParser::parse(argv[1], doc_config);
26  
27  // create search condition
28  Lux::SortCondition scond(Lux::SORT_SCORE, Lux::DESC);
29  //Lux::SortCondition scond(Lux::SORT_ATTR_STR, Lux::DESC, "created_at");
30  Lux::Paging paging(5);
31  Lux::Condition cond(scond, paging);
32  
33  // search for the query
34  Lux::Engine engine(doc_config);
35  if (!engine.open(argv[1], Lux::DB_RDONLY)) {
36    std::cerr << "engine.open failed" << std::endl;
37    exit(-1);
38  }
39  Lux::Searcher searcher(engine);
40   
41  Lux::ResultSet rs = searcher.search(argv[2], cond);
42  t2 = gettimeofday_sec();
43  
44  // for each search result
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;
49  rs.init_iter();
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;
58  }
59  
60  return 0;
61}
検索の流れは、 となります。

コンパイル & 実行

コンパイル
$ cd example
$ make
$ (index, search が作成される)
索引構築
$ ./index blogs < posts
$ (第一引数の"blogs"は設定ファイルの"xxx.document.conf" の部分を指定
検索
$ ./search blogs live
$ (結果)
ここまでがLuxでの検索までの流れになります。