Home

Awesome

<p align="center"> <img src="images/logos/2/cover.png#gh-light-mode-only" width="100%" /> <img src="images/logos/1/cover.png#gh-dark-mode-only" width="100%" /> </p>

kissearch

A fast fulltext search engine

Keep It Simple, Stupid

Features

Fields

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/
NameMemoryindex/add(Time)fuzzy search(Time)
Kissearch(server)16mb12s12ms
Kissearch(lib)16mb0.3s10ms
Typesense(server)118mb53s13ms

License

GNU Affero General Public License v3.0