一.ElasticSearch常用编程操作
1.索引相关操作
创建索引:
/**
* 创建索引
*/
@Test
public void onlyCreateIndex(){
//准备创建索引,指定索引名 执行创建的动作(get方法)
transportClient.admin().indices().prepareCreate("blog04").get();
}
删除索引:
/**
* 删除索引
*/
@Test
public void deleteIndex(){
transportClient.admin().indices().prepareDelete("blog04").get();
}
2.文档相关操作
创建文档:
//创建文档(向es中的索引中添加数据)
@Test
public void createDocument() throws Exception {
Article article = new Article(1L, "小米公司的手机", "小米手机真的很棒");
String jsonstr = objectMapper.writeValueAsstring(article);
//prepareIndex 创建索引
transportClient.prepareIndex("blog04","article","1")
//设置文档数据
.setSource(jsonstr,XContentType.JSON)
.get();
}
//创建文档 另外一种方式 文档就是JSON
@Test
public void createDocumentJson() throws Exception{
XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
.startObject()//{
.field("id",2)
.field("title","数据")
.field("content","数据测试 elasticsearch")
.endobject()//}
;
transportClient.prepareIndex("blog04","article","2")
//设置文档数据
.setSource(xContentBuilder)
.get();
}
修改文档:
修改文档和新增文档一样。当存在相同的文档的唯一ID的时候,便是更新。
删除文档:
//删除文档
@Test
public void deleteByDocument() {
transportClient.prepareDelete("blog04", "article", "2").get();
}
查询文档:
1.批量添加文档数据
@Test
public void createBatch1() throws Exception{
long start = System.currentTimeMillis();
//构建批量添加builder
BulkRequestBuilder bulkRequestBuilder = transportClient.prepareBulk();
for (long i = 0; i < 100; i++) {
Article article = new Article(i, "小米公司的手机"+i, "小米手机真的很棒"+i);
String jsonstr = objectMapper.writeValueAsstring(article);
IndexRequest request = new IndexRequest("blog04","article",i+"");
request.source(jsonstr,XContentType.JSON);
//添加请求对象buidler中
bulkRequestBuilder.add(request);
}
//批量进行导入
bulkRequestBuilder.get();
long end = System.currentTimeMillis();
System.out.println("花费时间:"+(end-start));
}
查询所有数据:
//查询所有的文档
@Test
public void MatchAllQuery() throws Exception{
//1.创建查询对象 设置查询条件
MatchAllQueryBuilder query = QueryBuilders.matchAllQuery();//select *
//2.执行查询
TimeValue keepAlive;
SearchResponse response = transportClient
.prepareSearch("blog04")//设置从哪一个索引中搜索
.setTypes("article")//设置搜索的类型
.setQuery(query) //设置查询条件
.get();//执行
//3.获取结果集
SearchHits hits = response.getHits();
System.out.println("根据条件命中的总记录数:"+hits.getTotalHits());//获取总结果数
//4.遍历结果集,打印数据
for (SearchHit hit : hits) {
String articleJSON = hit.getSourceAsstring();//相当于是一个一个的JSON的文档-->articlePOJO类型的JSON
System.out.println(articleJSON);
}
}
queryStringQuery():字符串查询
只能查询字符串类型数据,如果不指定字段,则会查询所有的字段的值
@Test
public void queryStringQuery() {
//1.创建查询对象,设置查询条件,执行查询动作
SearchResponse response = transportClient
.prepareSearch("blog04")
.setTypes("article")
.setQuery(QueryBuilders.queryStringQuery("手机").field("title"))
.get();
//2.获取结果集
SearchHits hits = response.getHits();
System.out.println("获取到的总命中数:" + hits.getTotalHits());
//3.循环遍历结果 打印
for (SearchHit hit : hits) {
String sourceAsstring = hit.getSourceAsstring();
System.out.println(sourceAsstring);
}
}
匹配查询:
// 特点:先进行分词 再进行匹配查询 再和合并返回数据 和创建倒排索引的时候分词器保持一致
@Test
public void MatchQuery(){
//1.创建查询对象 设置查询条件 执行查询
SearchResponse searchResponse = transportClient
.prepareSearch("blog04")
.setTypes("article")
//参数1 指定搜索的字段
//参数2 指定要搜索的值
.setQuery(QueryBuilders.matchQuery("title","米"))
.get();
//2.获取结果集
SearchHits hits = searchResponse.getHits();
System.out.println("根据条件命中的总记录数:"+hits.getTotalHits());
//3.打印
for (SearchHit hit : hits) {
System.out.println("搜索到的数据:"+hit.getSourceAsstring());
}
}
多字段匹配查询:
//多字段匹配查询 从多个字段中间分词再匹配搜索
@Test
public void MultiMatchQuery(){
//1.创建查询对象 设置条件 执行查询
SearchResponse searchResponse = transportClient
.prepareSearch("blog04")
.setTypes("article")
//参数1 指定要搜索的值
//参数2 指定从哪一些字段上进行搜索
.setQuery(QueryBuilders.multiMatchQuery("小米","title","content"))
.get();
//2.获取结果集
SearchHits hits = searchResponse.getHits();
System.out.println("根据条件命中的总记录数:"+hits.getTotalHits());
//3打印
for (SearchHit hit : hits) {
System.out.println("搜索到的数据:"+hit.getSourceAsstring());
}
}
模糊搜索:
// * 表示任意字符 可以占用也可以不占用字符空间 手机*
// ? 表示任意字符 占位符 占用一个字符空间 手机?
//模糊搜索
@Test
public void wildcardQuery(){
//1.创建查询对象 设置查询条件 执行查询
SearchResponse searchResponse = transportClient
.prepareSearch("blog04")
.setTypes("article")
//搜索手开头的数据
.setQuery(QueryBuilders.wildcardQuery("title","手机?"))
.get();
//2.获取结果集
SearchHits hits = searchResponse.getHits();
System.out.println("根据条件命中的总记录数:"+hits.getTotalHits());
//3.打印
for (SearchHit hit : hits) {
System.out.println("搜索的到的数据:"+hit.getSourceAsstring());
}
}
fuzzyQuery 相似度:
@Test
public void fuzzyQuery(){
//1.创建查询对象 设置查询条件 执行查询
SearchResponse searchResponse = transportClient
.prepareSearch("blog04")
.setTypes("article")
//
.setQuery(QueryBuilders.fuzzyQuery("title","小米手表" ))
.get();
//2.获取结果集
SearchHits hits = searchResponse.getHits();
System.out.println("根据条件命中的总记录数:"+hits.getTotalHits());
//3.打印
for (SearchHit hit : hits) {
System.out.println("搜索的到的数据:"+hit.getSourceAsstring());
}
}
范围查询
@Test
public void rangQuery(){
//1.创建查询对象 设置查询条件 执行查询
SearchResponse searchResponse = transportClient
.prepareSearch("blog04")
.setTypes("article")
// gte >=
// lte <=
//from true >=
// to true <=
.setQuery(QueryBuilders.rangeQuery("id").from(1,true).to(2,true))
.get();
//2.获取结果集
SearchHits hits = searchResponse.getHits();
System.out.println("根据条件命中的总记录数:"+hits.getTotalHits());
//3.打印
for (SearchHit hit : hits) {
System.out.println("搜索的到的数据:"+hit.getSourceAsstring());
}
}
多条件组合查询
//需求1 term 查询 title是小米 数据 并且 id范围在0-10 的数据
@Test
public void boolQuery(){ //{} where not condit1 contion
//1.创建子查询条件1
TermQueryBuilder queryBuilder1 = QueryBuilders.termQuery("title", "小米");
//2.创建子查询条件2
RangeQueryBuilder queryBuilder2 = QueryBuilders.rangeQuery("id").gte(0).lte(10);
//3.组合2个条件 再执行条件查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//4.创建查询对象 设置查询条件 执行查询
SearchResponse searchResponse = transportClient
.prepareSearch("blog04")
.setTypes("article")
//组合条件查询
.setQuery(boolQueryBuilder)
.get();
//5.获取结果集
SearchHits hits = searchResponse.getHits();
System.out.println("根据条件命中的总记录数:"+hits.getTotalHits());
//6.打印
for (SearchHit hit : hits) {
System.out.println("搜索的到的数据:"+hit.getSourceAsstring());
}
}
分页排序:
//分页排序 limit 0,10 (0-->(page-1)*rows 10: rows)
//排序 order by id desc/asc
@Test
public void pageSortQuery(){
//1.创建查询对象 设置查询条件 执行查询
SearchResponse searchResponse = transportClient
.prepareSearch("blog04")
.setTypes("article")
.setFrom(0) //page-1 * rows
.setSize(10) //rows
.addSort("id", SortOrder.DESC)
.setQuery(QueryBuilders.termQuery("title","小米"))
.get();
//2.获取结果集
SearchHits hits = searchResponse.getHits();
System.out.println("根据条件命中的总记录数:"+hits.getTotalHits());
//3.打印
for (SearchHit hit : hits) {
System.out.println("搜索的到的数据:"+hit.getSourceAsstring());
}
}
获取高亮的数据:
@Test
public void highlightQuery() throws IOException {
//0.设置高亮的字段 设置前缀和后缀
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder
.field("title")//高亮的字段
.preTags("<span style=\"color:red\">")//前缀 颜色
.postTags("</span>");
//1.创建查询对象 设置查询条件 执行查询
SearchResponse searchResponse = transportClient
.prepareSearch("blog04")
.setTypes("article")
.setFrom(0)//page-1 * rows
.setSize(10) //rows
.addSort("id",SortOrder.DESC)//默认是没有排序的
.Highlighter(highlightBuilder) //设置高亮的条件
.setQuery(QueryBuilders.matchQuery("title","小米"))
.get();
//2.获取结果集
SearchHits hits = searchResponse.getHits();
//3.打印
for (SearchHit hit : hits) {
//hit.getSourceAsstring() 获取到的数据是没有高亮的
System.out.println("搜索到的数据:"+hit.getSourceAsstring());
//获取高亮的数据
//key 是高亮的字段
//value 高亮的字段对应的数据值(高亮的内容)
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
//这里面有<span>....</span> 获取title高亮的字段
HighlightField highlightField = highlightFields.get("title");
//高亮的碎片 Text[] 说明 文本高亮是一个数组
Text[] fragments = highlightField.getFragments();
StringBuffer sb = new StringBuffer();
for (Text fragment : fragments) {
String highlight = fragment.string();
sb.append(highlight);
}
String s = sb.toString(); //高亮的数据 是title字段的高亮数据
Article article = objectMapper.readValue(hit.getSourceAsstring(), Article.class);
article.setTitle(s);
System.out.println(article.getId()+";"+article.getTitle()+"======="+article.getContent());
}
}