Skip to content

liameno/kissearch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

kissearch

A fast fulltext search engine

Keep It Simple, Stupid

Features

  • Strict Search
  • Fuzzy Search: Damerau Levenshtein Distance algorithm
  • Ranking: BM25 algorithm
  • Inverted Index
  • Stemmer: Porter2 algorithm
  • Tokenizer: with space
  • Load/Save: load from memory/file
  • Compression: when saving
  • Lib: C++
  • API

Fields

  • Number
  • Text
  • Keyword
  • Boolean

Lib

Build/Install

cd lib && mkdir build && cd build && cmake .. && make && sudo make install

CMake

target_link_libraries(${PROJECT_NAME} /usr/local/lib/libkissearch.so)

Example

example/
//full: example/example.cpp
int main() {
    const std::string file_name       = "index.db";
    const std::string field_name_text = "title";
    const std::string text_query      = "algorithms";
    
    document::search_options search_options_text;
    search_options_text.field_names = { field_name_text };

    collection collection;
    collection.documents.push_back(std::make_shared<document>());
    auto &document = *collection.documents.front();
    
    document.load(file_name);
    document.index_text_field(field_name_text);
    
    auto results = document.search(text_query, search_options_text);
    
    for (auto &result : results) {
        auto &field_id = result.first.find_field(field_name_number);
        auto &field = result.first.find_field(field_name_text);
        std::cout << field_id._number->value << " - " << field._text->value << " (score: " << result.second << ")" << std::endl;
    }
    
    document.save(file_name);
}

Deps

cd scripts && sh install_deps.sh

Server

Build

cd server && mkdir build && cd build && cmake .. && make

Start

./server

Use

GET /document/x #get document info 
# {
#   "entries":{"count":0},
#   "fields":[{"name":"a","type":"text"}],
#   "status":"ok"
# }
POST /document/x -d '{"a":"text"}' #create document 
# {
#   "status":"ok"
# }
POST /document/x/add -d '{"a":"example"}' #create entry 
# {
#   "status":"ok"
# }
POST document/x/index -d '' #index all text fields
# {
#   "status":"ok"
# }
POST /document/x/remove -d '{"q":"example","field_names":"a"}' #remove entries, only after index
#{  //default
#   "q": empty
#   "field_names": empty
#   "sort_by_score": true
#   "page": 1
#   "page_size": 10
#}
#}# {
#   "count":1,
#   "status":"ok"
# }
POST /document/x/search -d '{"q":"example","field_names":"a"}' #search entries, only after index
#{  //default
#   "q": empty
#   "field_names": empty
#   "sort_by_score": true
#   "page": 1
#   "page_size": 10
#}
# {
#   "count":1,
#   "found":[{"entry":{"a":"example"},"score":0.2876820724517809}]
#   "status":"ok"
# }

# Errors("status":"error"):
#   exception "message":"*what*"
#   already_exists_document "message":"Already Exists"
#   not_found_document "message":"Not Found"
#   not_found_field "message":"Not Found Field"
curl -XGET 0.0.0.0:8080/document/x -d
curl -XPOST 0.0.0.0:8080/document/x -d '{"a":"text"}'
curl -XPOST 0.0.0.0:8080/document/x/add -d '{"a":"example"}'
curl -XPOST 0.0.0.0:8080/document/x/index -d ''
curl -XPOST 0.0.0.0:8080/document/x/remove -d '{"q":"example","field_names":"a"}'
curl -XPOST 0.0.0.0:8080/document/x/search -d '{"q":"example","field_names":"a"}'

Comparison

comparison/
Name Memory index/add(Time) fuzzy search(Time)
Kissearch(server) 16mb 12s 12ms
Kissearch(lib) 16mb 0.3s 10ms
Typesense(server) 118mb 53s 13ms

License

GNU Affero General Public License v3.0