c++ 实现滚动查询Elasticsearch
2017-07-06 00:00
567 查看
[hadoop@iZ25s7cmfyrZ C_script]$ cat cpp_elasticsearch.cpp #include <iomanip> #include <iostream> #include <cctype> #include <string> #include <vector> #include <sstream> #include <boost/lexical_cast.hpp> #include <json/json.h> #include <boost/network/protocol/http/client.hpp> namespace http=boost::network::http; namespace network=boost::network; using std::cout; using std::endl; using std::string; typedef std::pair<string,Json::Value> SJPair; typedef std::vector<string> StrVec; string url_encode(const string &rhs){ std::ostringstream oss; std::setfill('0'); oss << std::hex; for(string::const_iterator cit=rhs.begin(); cit!=rhs.end(); ++cit){ string::value_type c= (*cit); if(std::isalnum(c)||c=='.'||c=='_'||c=='-'||c=='~'){ oss << c; continue; } oss << std::uppercase; oss << '%' << std::setw(2) << size_t(c); oss << std::nouppercase; } return oss.str(); } string postElasticsearch(const string &search, const string &query){ http::client client; http::client::request request(search); //如果请求方式为get时,创建请求的url为search和编码后的query拼接得到的 request << network::header("Content-Length", boost::lexical_cast<string>(query.size())); //request << network::header("Content-Type","application/x-www-form-urlencoded;"); request << network::header("Connection","close"); request << network::body(query); http::client::response response=client.post(request); //请求采用的是post return body(response); } std::pair<string, Json::Value> parseJsonFirst(const string &value){ Json::Value root; Json::Reader reader; reader.parse(value, root); string _scroll_id=root["_scroll_id"].asString(); Json::Value hits=root["hits"]; return std::make_pair(_scroll_id, hits); } int main(int argc, char** argv){ const string search= "http://eshost:9200/your_index/_search?scroll=1m&search_type=scan"; const string scroll= "http://eshost:9200/_search/scroll?scroll=1m"; const string query="{\"query\":{\"match_all\":{}}}"; //查询语句 string res=postElasticsearch(search, query); //cout << res << endl; SJPair rootpair=parseJsonFirst(res); string _scroll_id(rootpair.first); size_t total=(size_t)rootpair.second["total"].asInt(); //cout << _scroll_id << endl; int Tsize = total/(10*8)+1; StrVec vec; for(int i=0;i<Tsize;++i){ string test=postElasticsearch(scroll, _scroll_id); SJPair sonpair=parseJsonFirst(test); //cout << sonpair.first << endl; Json::Value hits=sonpair.second["hits"]; //cout << hits.size() << endl; for(auto it=hits.begin();it!=hits.end();++it){ Json::Value temp=*it; string _id=temp["_id"].asString(); Json::Value _source=temp["_source"]; string cell=_source["Clue_Entry_Cellphone"].asString(); //cout << _id <<" " << cell << endl; if(cell.length()>0) vec.push_back(cell); } _scroll_id=sonpair.first; if(vec.size()>1000) break; } cout << total << endl; cout << Tsize << endl; cout << vec.size() << endl; } }
为了使用 scroll,初始搜索请求应该在查询中指定 scroll 参数,这可以告诉 Elasticsearch 需要保持搜索的上下文环境多久(参考Keeping the search context alive),如
?scroll=1m。
curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m' -d ' { "query": { "match" : { "title" : "elasticsearch" } } } '
使用上面的请求返回的结果中包含一个
scroll_id,这个 ID 可以被传递给
scrollAPI 来检索下一个批次的结果。
curl -XGET 'localhost:9200/_search/scroll' -d' { "scroll" : "1m", "scroll_id" : "c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1" } '
GET或者
POST可以使用
URL不应该包含
index或者
type名字——这些都指定在了原始的
search请求中。
scroll参数告诉 Elasticsearch 保持搜索的上下文等待另一个
1m
scroll_id参数
每次对
scrollAPI 的调用返回了结果的下一个批次知道没有更多的结果返回,也就是直到
hits数组空了。
为了向前兼容,
scroll_id和
scroll可以放在查询字符串中传递。
scroll_id则可以在请求体中传递。
curl -XGET 'localhost:9200/_search/scroll?scroll=1m' -d 'c2Nhbjs2OzM0NDg1ODpzRlBLc0FXNlNyNm5JWUc1'
注意:初始搜索请求和每个后续滚动请求返回一个新的
_scroll_id——只有最近的
_scroll_id才能被使用。
如果请求指定了聚合(aggregation),仅仅初始搜索响应才会包含聚合结果。
使用 scroll-scan 的高效滚动
使用from and size的深度分页,比如说
?size=10&from=10000是非常低效的,因为
100,000排序的结果必须从每个分片上取出并重新排序最后返回
10条。这个过程需要对每个请求页重复。
scrollAPI 保持了哪些结果已经返回的记录,所以能更加高效地返回排序的结果。但是,按照默认设定排序结果仍然需要代价。
一般来说,你仅仅想要找到结果,不关心顺序。你可以通过组合
scroll和
scan来关闭任何打分或者排序,以最高效的方式返回结果。你需要做的就是将
search_type=scan加入到查询的字符串中:
curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m&search_type=scan' -d ' { "query": { "match" : { "title" : "elasticsearch" } } } '
设置
search_type为
scan可以关闭打分,让滚动更加高效。
相关文章推荐
- elasticsearch 分页查询实现方案
- Android 号码, 来电归属地 Jni 使用C++对二进制文件查询(二) C++实现篇
- 基于KMP算法的路径下文本查询程序的c++实现2.0版
- Elasticsearch 查询in 和 not in 的实现方式
- 文本查询程序(c++)set,vector,map容器实现
- 哈希表实现电话号码查询系统(c++)
- vs C++利用ado连接sqlserver2008实现一个查询功能
- elasticsearch 分页查询实现方案——Top K+归并排序
- C++实践笔记(二)----实现一个简单的文本查询程序
- Elasticsearch 查询in 和 not in 的实现方式
- cocos2dx-3.10 c++ 版实现滚动数字效果实现
- 纯c++实现之滚动窗口
- c++——容器实现文本查询程序
- POJ 3468 线段树区间修改查询(Java,c++实现)
- c++实现二叉树的插入、删除、查询、遍历和树形打印
- Spring Boot 整合 Elasticsearch,实现 function score query 权重分查询
- C++实现系统补丁查询-systeminfo系统命令查询补丁信息,c++从文件中查找特定的字符串
- ElasticSearch入门 第九篇:实现正则表达式查询的思路
- 查询txt文本信息行数(C和C++分别实现)
- 对sql查询语句组合查询的通用实现算法(c++版,java版)