Elasticsearch在站内搜索的使用

编程

1.elasticSearch 、solar与luence的区别

Lucene是一套信息检索工具包,并不包含搜索引擎系统,它包含了索引结构、读写索引工具、相关性工具、排序等功能,因此在使用Lucene时仍需要关注搜索引擎系统,例如数据获取、解析、分词等方面的东西。而solr和elasticsearch都是基于该工具包做的一些封装。

Solr是一个有HTTP接口的基于Lucene的查询服务器,封装了很多Lucene细节,自己的应用可以直接利用诸如 .../solr?q=abc 这样的HTTP GET/POST请求去查询,维护修改索引。
Elasticsearch也是一个建立在全文搜索引擎 Apache Lucene基础上的搜索引擎。采用的策略是分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。

solr利用zookpper进行分布式管理,而elasticsearch自身带有分布式协调管理功能;

solr比elasticsearch实现更加全面,solr官方提供的功能更多,而elasticsearch本身更注 重于核心功能,高级功能多由第三方插件提供;

solr在传统的搜索应用中表现好于elasticsearch,而elasticsearch在实时搜索应用方面比solr表现好!

3. Elasticsearch的适用场景

(1)维基百科,类似百度百科,牙膏,牙膏的维基百科,全文检索,高亮,搜索推荐
(2)The Guardian(国外新闻网站),类似搜狐新闻,用户行为日志(点击,浏览,收藏,评论)+社交网络数据(对某某新闻的相关看法),数据分析,给到每篇新闻文章的作者,让他知道他的文章的公众反馈(好,坏,热门,垃圾,鄙视,崇拜)

(3)Stack Overflow(国外的程序异常讨论论坛),IT问题,程序的报错,提交上去,有人会跟你讨论和回答,全文检索,搜索相关问题和答案,程序报错了,就会将报错信息粘贴到里面去,搜索有没有对应的答案

(4)GitHub(开源代码管理),搜索上千亿行代码
(5)电商网站,检索商品
(6)日志数据分析,logstash采集日志,ES进行复杂的数据分析(ELK技术,elasticsearch+logstash+kibana)

(7)商品价格监控网站,用户设定某商品的价格阈值,当低于该阈值的时候,发送通知消息给用户,比如说订阅牙膏的监控,如果高露洁牙膏的家庭套装低于50块钱,就通知我,我就去买

(8)BI系统,商业智能,Business Intelligence。比如说有个大型商场集团,BI,分析一下某某区域最近3年的用户消费金额的趋势以及用户群体的组成构成,产出相关的数张报表,**区,最近3年,每年消费金额呈现100%的增长,而且用户群体85%是高级白领,开一个新商场。ES执行数据分析和挖掘,Kibana进行数据可视化国内

(9)国内:站内搜索(电商,招聘,门户,等等),IT系统搜索(OA,CRM,ERP,等等),数据分析(ES热门的一个使用场景)

3.Elasticsearch入门

国内下载地址: https://thans.cn/mirror/elasticsearch.html

启动:./bin/elasticsearch 如果一切正常,Elastic 就会在默认的9200端口运行。这时,打开另一个命令行窗口,请求该端口,会得到说明信息。

其中elasticsearch.yum配置

cluster.name: elasticsearch

network.host: 0.0.0.0

http.port: 9200

安装中文分词:

https://www.cnblogs.com/ilovepython/p/11650139.html

IK分词器有两种分词模式:ik_max_word和ik_smart模式。

1、ik_max_word

会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、人民共和国、人民、共和国、大会堂、大会、会堂等词语。

2、ik_smart
会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。
 

程序中指定分词

@Document(indexName = "orders", type = "product")

@Mapping(mappingPath = "essearch/productIndex.json") // 解决IK分词不能使用问题

public class ProductDocument extends BaseDocument {

private static final long serialVersionUID = 1L;

private String productName;

private String productDesc;

public String getProductName() {

return productName;

}

public void setProductName(String productName) {

this.productName = productName;

}

public String getProductDesc() {

return productDesc;

}

public void setProductDesc(String productDesc) {

this.productDesc = productDesc;

}

}

{

"properties": {

"createTime": {

"type": "long"

},

"productDesc": {

"type": "text",

"analyzer": "ik_max_word",

"search_analyzer": "ik_max_word"

},

"productName": {

"type": "text",

"analyzer": "ik_max_word",

"search_analyzer": "ik_max_word"

},

"updateTime": {

"type": "long"

}

}

}

搜索逻辑实现

@Service

public class BaseSearchServiceImpl<T> implements BaseSearchService<T> {

@Resource

protected ElasticsearchTemplate elasticsearchTemplate;

@Override

public List<T> query(String keyword, Class<T> clazz) {

SearchQuery searchQuery = new NativeSearchQueryBuilder()

.withQuery(new QueryStringQueryBuilder(keyword))

.withSort(SortBuilders.scoreSort().order(SortOrder.DESC))

.build();

return elasticsearchTemplate.queryForList(searchQuery,clazz);

}

/**

* 高亮显示

*/

@Override

public List<Map<String,Object>> queryHit(String keyword,String indexName,String ... fieldNames) {

// 构造查询条件,使用标准分词器.

QueryBuilder matchQuery = createQueryBuilder(keyword,fieldNames);

// 设置高亮,使用默认的highlighter高亮器

HighlightBuilder highlightBuilder = createHighlightBuilder(fieldNames);

// 设置查询字段

SearchResponse response = elasticsearchTemplate.getClient().prepareSearch(indexName)

.setQuery(matchQuery)

.highlighter(highlightBuilder)

.setSize(10000) // 设置一次返回的文档数量,最大值:10000

.get();

// 返回搜索结果

SearchHits hits = response.getHits();

return getHitList(hits);

}

/**

* 高亮显示,返回分页

*/

@Override

public Page<Map<String, Object>> queryHitByPage(int pageNo,int pageSize, String keyword, String indexName, String... fieldNames) {

// 构造查询条件,使用标准分词器.

QueryBuilder matchQuery = createQueryBuilder(keyword,fieldNames);

// 设置高亮,使用默认的highlighter高亮器

HighlightBuilder highlightBuilder = createHighlightBuilder(fieldNames);

// 设置查询字段

SearchResponse response = elasticsearchTemplate.getClient().prepareSearch(indexName)

.setQuery(matchQuery)

.highlighter(highlightBuilder)

.setFrom((pageNo-1) * pageSize)

.setSize(pageNo * pageSize) // 设置一次返回的文档数量,最大值:10000

.get();

// 返回搜索结果

SearchHits hits = response.getHits();

Long totalCount = hits.getTotalHits();

Page<Map<String, Object>> page = new Page<>(pageNo,pageSize,totalCount.intValue());

page.setList(getHitList(hits));

return page;

}

/**

* 构造查询条件

*/

private QueryBuilder createQueryBuilder(String keyword, String... fieldNames){

// 构造查询条件,使用标准分词器.

return QueryBuilders.multiMatchQuery(keyword,fieldNames) // matchQuery(),单字段搜索

.analyzer("ik_max_word")

.operator(Operator.OR);

}

/**

* 构造高亮器

*/

private HighlightBuilder createHighlightBuilder(String... fieldNames){

// 设置高亮,使用默认的highlighter高亮器

HighlightBuilder highlightBuilder = new HighlightBuilder()

// .field("productName")

.preTags("<span style="color:red">")

.postTags("</span>");

// 设置高亮字段

for (String fieldName: fieldNames) highlightBuilder.field(fieldName);

return highlightBuilder;

}

/**

* 处理高亮结果

*/

private List<Map<String,Object>> getHitList(SearchHits hits){

List<Map<String,Object>> list = new ArrayList<>();

Map<String,Object> map;

for(SearchHit searchHit : hits){

map = new HashMap<>();

// 处理源数据

map.put("source",searchHit.getSourceAsMap());

// 处理高亮数据

Map<String,Object> hitMap = new HashMap<>();

searchHit.getHighlightFields().forEach((k,v) -> {

String hight = "";

for(Text text : v.getFragments()) hight += text.string();

hitMap.put(v.getName(),hight);

});

map.put("highlight",hitMap);

list.add(map);

}

return list;

}

@Override

public void deleteIndex(String indexName) {

elasticsearchTemplate.deleteIndex(indexName);

}

}

实例应用:

https://gitee.com/pengchua/elasticsearch

 

以上是 Elasticsearch在站内搜索的使用 的全部内容, 来源链接: utcz.com/z/517425.html

回到顶部