Skip to content
/ Qute Public

A lightweight search query execution engine in C++

License

Notifications You must be signed in to change notification settings

hczhu/Qute

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Qute

Qute is a C++ library for a lightweight search query execution engine. Qute supports Qute query language.
See the code snippet below for a simple example of using Qute. The full compilable code is at examples/full_text_search.cc

const std::vector<std::string> kMarkTwainQuotes = {
    "A man is never more truthful than when he acknowledges himself a liar.",
    "I don't give a damn for a man that can only spell a word one way.",
    "The human race has one really effective weapon, and that is laughter.",
    "Loyalty to petrified opinion never yet broke a chain or freed a human soul.",
};

...

int main() {
  IteratorFactory iteratorFactory;
  qute::QueryParser queryParser(iteratorFactory);
  // Search for quotes having
  //     "man" and "liar"
  //   or having "human" but without "weapon".
  const std::string query = R"(
    (or (and tag:man_liar man liar )
        (diff tag:human-weapon human weapon)
    )
  )";
  auto itr = queryParser.getIterator(query);
  std::cout << "Search results:" << std::endl;
  for (; itr->valid(); itr->next()) {
    std::cout << "  " << kMarkTwainQuotes[itr->value()];
    auto tags = itr->getTags();
    if (!tags.empty()) {
      std::cout << " (" << tags[0] << ")";
    }
    std::cout << std::endl;
  }
  // Output
  /* 
   * Search results:
   *   A man is never more truthful than when he acknowledges himself a liar. (man_liar)
   *   Loyalty to petrified opinion never yet broke a chain or freed a human soul. (human-weapon)
   * 
   */
  return 0;
}

Qute query language

Qute query language is a Context-free Language following the following grammar

Query :-> Term | (Operator Query_list) | (Operator Query_list) | (Operator Query Query)

Operator :-> Operator_without_tag | (Operator_without_tag tag:Token)

Operator_without_tag :-> and | or | diff

Query_list :-> Query Query_list | Term

Term :-> Token

Token :-> any string consisting of no whitespace, '(' or ')'.

The following one is a fairly complex Qute query example

(diff
    ( or tag:or (and tag:meta facebook c:facebook)
         (and tag:goog google c:google)
         (or tag:aapl apple)
    )
    nothing
)

How to use Qute library

Qute can be easily imported to any C++ project built by Bazel.
Add the following content to your Bazel WORKSPACE file.

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

git_repository(
    name = "com_github_hczhu_qute",
    commit = "27f35f48390b5b3aa218ad6f55276d8567f96518",
    remote = "https://github.com/hczhu/Qute.git",
)

http_archive(
    name = "com_github_gflags_gflags",
    sha256 = "34af2f15cf7367513b352bdcd2493ab14ce43692d2dcd9dfc499492966c64dcf",
    strip_prefix = "gflags-2.2.2",
    urls = ["https://github.com/gflags/gflags/archive/v2.2.2.tar.gz"],
)

http_archive(
    name = "com_github_glog",
    sha256 = "8a83bf982f37bb70825df71a9709fa90ea9f4447fb3c099e1d720a439d88bad6",
    strip_prefix = "glog-0.6.0",
    urls = ["https://github.com/google/glog/archive/refs/tags/v0.6.0.tar.gz"],
)

To depend on Qute, add the following dependancy to your Bazel target.

    deps = [
        "@com_github_hczhu_qute//:qute",
    ],

Also specify compiler option -std=c++2a in either Bazel command line or in the .bazelrc file.

build --cxxopt='-std=c++2a'

See an example C++ project depending on Qute

Build

Qute is built and tested on Linux. Qute uses Bazel to build. Run the following commands in a Linux Shell to build Qute library.

git clone https://github.com/hczhu/Qute.git
cd Qute
./install-bazel.sh
bazel build :qute

Run Qute tests

bazel test test/...

Run the examples

bazel run examples/...