1. Elasticsearch 5.5 入门必会(一)html
2. Elasticsearch 5.5 入门必会之Java client(二)java
咱们先看个简单的代码:mysql
@Test public void match() { SearchRequestBuilder requestBuilder = client.prepareSearch("megacorp").setTypes("employee") .setQuery(QueryBuilders.matchQuery("about", "rock climbing")); System.out.println(requestBuilder.toString()); SearchResponse response = requestBuilder.execute().actionGet(); System.out.println(response.status()); if (response.status().getStatus() == 200) { for (SearchHit hits : response.getHits().getHits()) { System.out.println(hits.getSourceAsString()); } } }
===============================================================spring
/** * matchphrase使用,短语精准匹配 */ @Test public void matchPhrase() { SearchRequestBuilder requestBuilder = client.prepareSearch("megacorp").setTypes("employee") .setQuery(QueryBuilders.matchPhraseQuery("about", "rock climbing")); System.out.println(requestBuilder.toString()); SearchResponse response = requestBuilder.execute().actionGet(); System.out.println(response.status()); if (response.status().getStatus() == 200) { for (SearchHit hits : response.getHits().getHits()) { System.out.println(hits.getSourceAsString()); } } }
上面的代码你能够理解为:sql
select * from megacorp_employee where about like '%rock climbing%'
@Test public void aggregation() { SearchRequestBuilder searchBuilder = client.prepareSearch("megacorp").setTypes("employee") .addAggregation(AggregationBuilders.terms("by_interests").field("interests") .subAggregation(AggregationBuilders.terms("by_age").field("age")).size(10)); System.out.println(searchBuilder.toString()); SearchResponse response = searchBuilder.execute().actionGet(); if (response.status().getStatus() == 200) { for (SearchHit hits : response.getHits().getHits()) { System.out.println(hits.getSourceAsString()); } } StringTerms terms = response.getAggregations().get("by_interests"); for (StringTerms.Bucket bucket : terms.getBuckets()) { System.out.println("-interest:" + bucket.getKey() + "," + bucket.getDocCount()); if (bucket.getAggregations() != null && bucket.getAggregations().get("by_age") != null) { LongTerms ageTerms = bucket.getAggregations().get("by_age"); for (LongTerms.Bucket bucket2 : ageTerms.getBuckets()) { System.out.println("--------by age:" + bucket2.getKey() + "," + bucket2.getDocCount()); } } } }
至关于SQL里面的数据库
select interests,age,count(1) from megacorp_employee group by interests,age limit 10
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); if(StringUtils.isNotBlank(searchParam.getSearchWords())) { BoolQueryBuilder mutiShould = QueryBuilders.boolQuery(); for(String column : searchType.getSearchColumn()) { mutiShould.should(QueryBuilders.termQuery(column+KEYWORD, searchParam.getSearchWords().trim())); } queryBuilder.must().add(mutiShould); } // 科室编码过滤 if(StringUtils.isNotBlank(searchParam.getDeptNo())) { queryBuilder.must(QueryBuilders.termQuery("admissward"+KEYWORD, searchParam.getDeptNo().trim())); } /** * 有时间范围 */ if(searchParam.getTimeType() > 0 && searchParam.getTimeType() < 3) { Date startDate = searchParam.getStartDate(); Date endDate = searchParam.getEndDate(); RangeQueryBuilder rangeBuilder = null; // 入院日期 if(searchParam.getTimeType() == 1) { if(null != startDate) { rangeBuilder = QueryBuilders.rangeQuery("admissdate").gte(startDate.getTime()); } if(null != endDate) { if(null == rangeBuilder) { rangeBuilder = QueryBuilders.rangeQuery("admissdate").lte(endDate.getTime()); } else { rangeBuilder.lte(endDate.getTime()); } } // 出院日期 } else if(searchParam.getTimeType() == 2) { if(null != startDate) { rangeBuilder = QueryBuilders.rangeQuery("disdate").gte(startDate.getTime()); } if(null != endDate) { if(null == rangeBuilder) { rangeBuilder = QueryBuilders.rangeQuery("disdate").lte(endDate.getTime()); } else { rangeBuilder.lte(endDate.getTime()); } } } if(null != rangeBuilder) { queryBuilder.must().add(rangeBuilder); } } SearchRequestBuilder searchBuilder = client.prepareSearch(searchType.getIndexType().get_index()) .setTypes(searchType.getIndexType().get_type()) .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) .setQuery(queryBuilder) .addSort(StringUtils.isBlank(searchType.getSortColumn())?SCORE:searchType.getSortColumn() , searchType.getOrder()==null?SortOrder.DESC:searchType.getOrder()) .setFrom(pager.getStartRow()).setSize(pager.getPageSize()).setExplain(true); SearchResponse response = searchBuilder.execute().actionGet(); long end = System.currentTimeMillis(); logger.info("searchMutiField request indexType:{},searchparam:{},orderColumn:{},orderBy:{}.total hits:{},cost 【{}】 ms" ,searchType.getIndexType().get_type(),queryBuilder.toString(),searchType.getSearchColumn(), searchType.getOrder(),response.getHits().totalHits,(end-start));
上面的稍微复杂一点,是我生产环境的部分代码,对应的SQL语句是,其实你看到这一个例子应该就大概知道了怎样用SQL转化为代码,BoolQueryBuilder.must就至关于SQL里面的 AND 的概念,Should就是ORexpress
select * from table_name where (column1='searchwords' or column2='searchwords' .. ) and admissward='123456' and admissdate > '1412000212112' and admissdate < '141976521211' limit 10 --个人判断逻辑是若是是入院日期查询就 admissdate > startdate and admissdate < endate --若是是出院日期 就disdate > startdate and disdate < enddate --这个逻辑我就不分开写出来了,省略了
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapping SYSTEM "elastic-config.dtd"> <!-- 属性参考 https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-store.html --> <mapping > <!-- <datasource id="dataSource1" ref="springDataSource"> </datasource>--> <datasource id="dataSource" > <username>admin</username> <password>admin</password> <jdbcurl>jdbc:mysql://127.0.0.1:3306/message?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=round&useCursorFetch=true&verifyServerCertificate=false&useSSL=false</jdbcurl> <driver>com.mysql.jdbc.Driver</driver> </datasource> <sql-mappings> <sql-mapping data-source-id="dataSource"> <!-- 全量索引 构建 每周星期天3点执行 --> <full-sql> <sql>SELECT * FROM HAHA ORDER BY ID ASC</sql> <expression>0 0 3 ? * SUN</expression> </full-sql> <!-- 每日增量索引构建 --> <incr-sql> <sql>SELECT * FROM HAHA WHERE GMT_CREATE > DATE_ADD(NOW(),INTERVAL -2 DAY) ORDER BY ID ASC</sql> <expression>0 0 2 * * ?</expression> </incr-sql> <search-info> <index>test</index> <type>test</type> <columns> <column index-column="idindex" data-type="integer" sql-column="id" index="not_analyzed" store="no" /> <column index-column="nameindex" data-type="string" sql-column="name" index="not_analyzed" store="no" /> <column index-column="blobtindex" data-type="byte" sql-column="blobt" index="not_analyzed" store="no" /> <column index-column="datesindex" data-type="date" sql-column="ttt" store="no" format="yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" locale="CHINA" /> <column index-column="tinytestindex" data-type="boolean" sql-column="tinytest" index="not_analyzed" store="no" /> <column index-column="moneysindex" data-type="string" sql-column="moneys" index="not_analyzed" store="no" /> <column index-column="ggggindex" data-type="date" sql-column="gggg" format="yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" store="no" /> </columns> </search-info> </sql-mapping> </sql-mappings> </mapping>
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); formatter.setTimeZone(TimeZone.getTimeZone("UTC")); SimpleDateFormat standard = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { return standard.format(formatter.parse(admiss_time)); } catch (ParseException e) { return null; }
//咱们只须要获取当前咱们本地时间以后getTime传入便可 admissdate >= xxxxx QueryBuilders.rangeQuery("admissdate").gte(startDate.getTime());
Map<String,Object> map = new HashMap<String,Object>(); map.put("id", 1); //map.put('test',456); map.put("test", 1); //map.put('hehe',567); map.put("hehe", 2); IndexResponse response = client.prepareIndex("emr_document2", "user_info2",map.get('id').toString()) .setSource(map) .get();
我单位乙方提供的数据库没有作比较好的分表方案,历史数据出院一个星期就转入B表,致使不少系统没法正常调用出院患者的病历数据和病人主索引信息,如今已经引入了搜索以后,正常提供所有患者主索引信息查询服务,用起来很爽!病历数据+患者主索引数据 总共不超过500W,查询速度至关快,都在20ms如下!app