// Test connection with node. bool ElasticSearch::isActive() { Json::Object root; try { _http.get(0, 0, &root); } catch(Exception& e){ printf("get(0) failed in ElasticSearch::isActive(). Exception caught: %s\n", e.what()); return false; } catch(std::exception& e){ printf("get(0) failed in ElasticSearch::isActive(). std::exception caught: %s\n", e.what()); return false; } catch(...){ printf("get(0) failed in ElasticSearch::isActive().\n"); return false; } if(root.empty()) return false; if(!root.member("status") || root["status"].getInt() != 200){ printf("Status is not 200. Cannot find Elasticsearch Node.\n"); return false; } return true; }
/// Index a document. bool ElasticSearch::index(const std::string& index, const std::string& type, const std::string& id, const Json::Object& jData){ if(_readOnly) return false; std::stringstream url; url << index << "/" << type << "/" << id; std::stringstream data; data << jData; Json::Object result; _http.put(url.str().c_str(), data.str().c_str(), &result); if(!result.member("created")) EXCEPTION("The index induces error."); if(result.getValue("created")) return true; std::cout << "endPoint: " << index << "/" << type << "/" << id << std::endl; std::cout << "jData" << jData.pretty() << std::endl; std::cout << "result" << result.pretty() << std::endl; EXCEPTION("The index returns ok: false."); return false; }
// Test if document exists bool ElasticSearch::exist(const std::string& index, const std::string& type, const std::string& id){ std::stringstream url; url << index << "/" << type << "/" << id; Json::Object result; _http.get(url.str().c_str(), 0, &result); if(!result.member("found")){ std::cout << result << std::endl; EXCEPTION("Database exception, field \"found\" must exist."); } return result.getValue("found"); }
// Request the document number of type T in index I. long unsigned int ElasticSearch::getDocumentCount(const char* index, const char* type){ std::ostringstream oss; oss << index << "/" << type << "/_count"; Json::Object msg; _http.get(oss.str().c_str(),0,&msg); size_t pos = 0; if(msg.member("count")) pos = msg.getValue("count").getUnsignedInt(); else printf("We did not find \"count\" member.\n"); return pos; }
/// Delete the document by index/type. bool ElasticSearch::deleteAll(const char* index, const char* type){ if(_readOnly) return false; std::ostringstream uri, data; uri << index << "/" << type << "/_query"; data << "{\"query\":{\"match_all\": {}}}"; Json::Object msg; _http.remove(uri.str().c_str(), data.str().c_str(), &msg); if(!msg.member("_indices") || !msg["_indices"].getObject().member(index) || !msg["_indices"].getObject()[index].getObject().member("_shards")) return false; if(!msg["_indices"].getObject()[index].getObject()["_shards"].getObject().member("failed")) return false; return (msg["_indices"].getObject()[index].getObject()["_shards"].getObject()["failed"].getInt() == 0); }
// Update a document field. bool ElasticSearch::update(const std::string& index, const std::string& type, const std::string& id, const std::string& key, const std::string& value){ if(_readOnly) return false; std::stringstream url; url << index << "/" << type << "/" << id << "/_update"; std::stringstream data; data << "{\"doc\":{\"" << key << "\":\""<< value << "\"}}"; Json::Object result; _http.post(url.str().c_str(), data.str().c_str(), &result); if(!result.member("_version")) EXCEPTION("The update failed."); return true; }
// Update doccument fields. bool ElasticSearch::update(const std::string& index, const std::string& type, const std::string& id, const Json::Object& jData){ if(_readOnly) return false; std::stringstream url; url << index << "/" << type << "/" << id << "/_update"; std::stringstream data; data << "{\"doc\":" << jData; data << "}"; Json::Object result; _http.post(url.str().c_str(), data.str().c_str(), &result); if(result.member("error")) EXCEPTION("The update doccument fields failed."); return true; }
/// Search API of ES. long ElasticSearch::search(const std::string& index, const std::string& type, const std::string& query, Json::Object& result, const int n_result=10){ std::stringstream url; url << index << "/" << type << "/_search?size=" << n_result; _http.post(url.str().c_str(), query.c_str(), &result); if(!result.member("timed_out")){ std::cout << url.str() << " -d " << query << std::endl; std::cout << "result: " << result << std::endl; EXCEPTION("Search failed."); } if(result.getValue("timed_out")){ std::cout << "result: " << result << std::endl; EXCEPTION("Search timed out."); } return result.getValue("hits").getObject().getValue("total").getLong(); }
//retrive all documemnts of a class int ElasticSearch::fullScan(const std::string& index, const std::string& type, const std::string& query, Json::Array& resultArray, int scrollSize) { // Get the scroll id std::stringstream scrollUrl; scrollUrl << index << "/" << type << "/_search?search_type=scan&scroll=10m&size=" << scrollSize; Json::Object scrollObject; _http.post(scrollUrl.str().c_str(),query.c_str(),&scrollObject); if(!scrollObject.member("hits")) EXCEPTION("Result corrupted, no member \"hits\"."); if(!scrollObject.getValue("hits").getObject().member("total")) EXCEPTION("Result corrupted, no member \"total\" nested in \"hits\"."); int total = scrollObject.getValue("hits").getObject().getValue("total").getInt(); std::string scrollId = scrollObject["_scroll_id"].getString(); int count = 0; while(count < total) { Json::Object result; _http.rawpost("_search/scroll?scroll=10m", scrollId.c_str(), &result); // Kepp the new scroll id we received to inject in the next iteration. scrollId = result["_scroll_id"].getString(); for(const Json::Value& value : result["hits"].getObject()["hits"].getArray()){ resultArray.addElement(value); ++count; } } if(count != total) EXCEPTION("Result corrupted, total is different from count."); return total; }
/// Index a document with automatic id creation std::string ElasticSearch::index(const std::string& index, const std::string& type, const Json::Object& jData){ if(_readOnly) return ""; std::stringstream url; url << index << "/" << type << "/"; std::stringstream data; data << jData; Json::Object result; _http.post(url.str().c_str(), data.str().c_str(), &result); if(!result.member("created") || !result.getValue("created")){ std::cout << "url: " << url.str() << std::endl; std::cout << "data: " << data.str() << std::endl; std::cout << "result: " << result.str() << std::endl; EXCEPTION("The index induces error."); } return result.getValue("_id").getString(); }