SpringBoot环境下ElasticSearch的使用

  1. 专业全文索引是怎么处理的?
    全文搜索引擎目前主流的索引技术就是倒排索引的方式。
    传统的保存数据的方式都是: 记录→单词
    而倒排索引的保存数据的方式是: 单词→记录
    例如
    搜索“红海行动”
    但是数据库中保存的数据如图:
    在这里插入图片描述

那么搜索引擎是如何能将两者匹配上的呢?
基于分词技术构建倒排索引:
首先每个记录保存数据时,都不会直接存入数据库。系统先会对数据进行分词,然后以倒排索引结构保存。如下:
在这里插入图片描述

然后等到用户搜索的时候,会把搜索的关键词也进行分词,会把“红海行动”分词分成:红海和行动两个词。
这样的话,先用红海进行匹配,得到id=1和id=2的记录编号,再用行动匹配可以迅速定位id为1,3的记录。
那么全文索引通常,还会根据匹配程度进行打分,显然1号记录能匹配的次数更多。所以显示的时候以评分进行排序的话,1号记录会排到最前面。而2、3号记录也可以匹配到。
2. 搜索引擎介绍
lucene是一个提供全文搜索功能类库的核心工具包,而真正使用它还需要一个完善的服务框架搭建起来的应用。
目前市场上流行的搜索引擎软件有ElaticSearch和Solr,ElaticSearch在目前的市场的占有率更高。
3. ElaticSearch的使用场景
a) 为用户提供按关键字查询的全文搜索功能。
b) 著名的ELK框架(ElasticSearch,Logstash,Kibana),实现企业海量日志的处理分析的解决方案。大数据领域的重要一份子。

4.ElaticSearch的基本概念

cluster 整个elasticsearch 默认就是集群状态,整个集群是一份完整、互备的数据。
node 集群中的一个节点,一般只一个进程就是一个node
shard 分片,即使是一个节点中的数据也会通过hash算法,分成多个片存放,默认是5片。
index 相当于rdbms的database, 对于用户来说是一个逻辑数据库,虽然物理上会被分多个shard存放,也可能存放在多个node中。
type 类似于rdbms的table,但是与其说像table,其实更像面向对象中的class , 同一Json的格式的数据集合
document 类似于rdbms的 row、面向对象里的objecfield 相当于字段、属性
  1. ElaticSearch的依赖
    SpringBoot中可以自动管理控制elasticsearch的版本
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
    <groupId>io.searchbox</groupId>
    <artifactId>jest</artifactId>
    <version>5.3.3</version>
</dependency>
<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
    <version>4.5.1</version>
</dependency>

ELASTICSEARCH的使用

1.设计存入ES的数据结构

PUT gmall
{
  "mappings": {
    "SkuInfo":{
      "properties": {
        "id":{
          "type": "keyword"
          , "index": false
        },
        "price":{
          "type": "double"
        },
         "skuName":{
          "type": "text",
          "analyzer": "ik_max_word"
        },
        "skuDesc":{
          "type": "text",
          "analyzer": "ik_smart"
        },
        "catalog3Id":{
          "type": "keyword"
        },
        "skuDefaultImg":{
          "type": "keyword",
          "index": false
        },
        "skuAttrValueList":{
          "properties": {
            "valueId":{
              "type":"keyword"
            }
          }
        }
      }
    }
  }
}
		

2.将数据存入ES中

//将skuLsInfo导入到es中
Index index = new Index.Builder(skuLsInfo).index("gmall").type("SkuLsInfo")
	id(skuLsInfo.getId()).build();
jestClient.execute(index)

3.ES的数据查询

//ES的数据查询
    @Test
    public void ESqueryData() throws IOException {
        //生成Dsl语句
        String dsl = getMyDsl();

        //查询
        Search search = new Search.Builder(dsl).addIndex("gmall").addType("SkuLsInfo").build();

        //执行查询
        SearchResult searchResult = jestClient.execute(search);

        List<SearchResult.Hit<SkuLsInfo, Void>> hits = searchResult.getHits(SkuLsInfo.class);
        ArrayList<SkuLsInfo> SkuLsInfoList = new ArrayList<>();
        for (SearchResult.Hit<SkuLsInfo, Void> hit : hits) {
            SkuLsInfo source = hit.source;
            SkuLsInfoList.add(source);
        }
        System.out.println(SkuLsInfoList);

    }

    public String getMyDsl() {

        //查询语句封装
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //联合查询
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

//        TermQueryBuilder termQueryBuilder = new TermQueryBuilder(null,null);
//        boolQueryBuilder.filter(termQueryBuilder);

        MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder("skuName","苹果");
        boolQueryBuilder.must(matchQueryBuilder);

        searchSourceBuilder.query(boolQueryBuilder);
        //高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("skuName");
        searchSourceBuilder.highlight(highlightBuilder);
        return searchSourceBuilder.toString();
    }

4.实际代码

`@Service
public class ListServiceImpl implements ListService {

@Autowired
JestClient jestClient;

/**
 * 完成ES的查询
 * @param skuLsParam 入参属性
 * @return List<SkuLsInfo> 出参属性集合
 */
@Override
public List<SkuLsInfo> list(SkuLsParam skuLsParam) {
    List<SkuLsInfo> SkuLsInfoList = new ArrayList<>();
    //生成Dsl语句
    String dsl = getMyDsl(skuLsParam);

    //查询
    Search search = new Search.Builder(dsl).addIndex("gmall")
    	.addType("SkuLsInfo").build()
    //执行查询
    SearchResult searchResult = null;
    try {
        searchResult = jestClient.execute(search);
    } catch (IOException e) {
        e.printStackTrace();
    }
    Long total = searchResult.getTotal();
    if (total>0){
        List<SearchResult.Hit<SkuLsInfo, Void>> hits = searchResul 
	    	.getHits(SkuLsInfo.class)
        for (SearchResult.Hit<SkuLsInfo, Void> hit : hits) {
            SkuLsInfo source = hit.source;
            SkuLsInfoList.add(source);
        }
    }

    return SkuLsInfoList;
}

public String getMyDsl(SkuLsParam skuLsParam) {

    //查询语句封装
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

    //联合查询
    BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

    //三级分类id
    String catalog3Id = skuLsParam.getCatalog3Id();
    if (StringUtils.isNotBlank(catalog3Id)) {
        TermQueryBuilder termQueryBuilder =    
			new TermQueryBuilder("catalog3Id", catalog3Id);
        boolQueryBuilder.filter(termQueryBuilder);
    }
    //分类属性值
    String[] valueId = skuLsParam.getValueId();
    if (valueId != null && valueId.length > 0) {
        for (String id : valueId) {
            TermQueryBuilder termQueryBuilder                 
	 			new TermQueryBuilder("skuAttrValueList.valueId", id);
            boolQueryBuilder.filter(termQueryBuilder);
        }
    }
    //关键字
    String keyword = skuLsParam.getKeyword();
    if (StringUtils.isNotBlank(keyword)) {
        MatchQueryBuilder matchQueryBuilde            
			= new MatchQueryBuilder("skuName", keyword);
        boolQueryBuilder.must(matchQueryBuilder);
    }
    searchSourceBuilder.query(boolQueryBuilder);

    //高亮
    HighlightBuilder highlightBuilder = new HighlightBuilder();
    highlightBuilder.field("skuName");
    searchSourceBuilder.highlight(highlightBuilder);

    //查询数量
    searchSourceBuilder.from(0);
    searchSourceBuilder.size(100);
    return searchSourceBuilder.toString();
}

}

猜你喜欢

转载自blog.csdn.net/qq_38697437/article/details/86582810