【记录】全文搜索引擎elasticsearch

全文搜索引擎elasticSearch

es尿崩式更新,三两天就发布一个新版本,到现在三两年已经从1.0.0到7.x上百个版本,版本与springboot对应、语法都有不同,文档还不好找,坑

第五部分记录6.2.2版本的增删改查操作、嵌套,网上现有的代码基本都不能用

 

零 有价值的参考资料

  1. 整体介绍,包括与springboot版本对应、搜索语句的详细说明
  2. FiledType说明
  3. 各种查询的java代码例子

 

一 安装

  1. 安装jdk
  2. elasticsearch官网下载 (默认9200端口,bin目录下elasticsearch或elasticsearch.bat启动)
  3. 可视化kibana官网下载 (默认5601端口,bin目录下kibana启动)
  4. 中文分词插件IK下载 解压到elasticsearch安装目录下plugins/ik,重启es
  5. head插件,可视化配置、检索、编辑数据
  6. logstash数据同步

二 功能用处

* 搜索引擎:只需要elasticsearch本体,webapp端引入依赖,通过相关api交互增删改查;

* 聚合数据分析:需要kibana可视化、logstash日志插件,分析数据;

三 结构

与数据库区分,有自己的一套库专门用于检索,通过logstash或业务同步操作来同步数据。

四 整合sb

1 pom依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

2 配置

# ELASTICSEARCH (ElasticsearchProperties)
# Elasticsearch cluster name.
spring.data.elasticsearch.cluster-name=elasticsearch_coldxiangyu
# Comma-separated list of cluster node addresses.
spring.data.elasticsearch.cluster-nodes= 127.0.0.1:9300
# Whether to enable Elasticsearch repositories.
spring.data.elasticsearch.repositories.enabled=true

3 建立接口

package com.coldxiangyu.elasticsearch.repository;
import com.coldxiangyu.elasticsearch.bean.QuestionBean;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

/**
 * 接口关系:
 * ElasticsearchRepository --> ElasticsearchCrudRepository --> PagingAndSortingRepository --> CrudRepository
 */
public interface QuestionRepository extends ElasticsearchRepository<QuestionBean, String> {

    //Optional<BookBean> findById(String id);

}

ps:

  • 所继承的父类里提供了findAll、findById等一些默认方法,可直接使用;例如
findAll——查询所有数据,返回的是个迭代器

findById——根据id(主键)查询
  • 此接口中可声明有一定格式的接口方法,可直接使用,会自动解析,例如
1 例子
findByAaBetweenOrderByBbDesc——查询Aa字段介于两个入参之间(包含边界)的数据,按Bb倒序排序
findByNameStartingWith——查询Name字段开头为入参的数据
Long countByLastname(String lastname)——计数

2 为明确嵌套的属性,可使用_分隔
findByAaBbCc 会识别为AaBbCc,找不到再识别AaBb和Cc。可直接写findByAa_BbCc,就会寻找Aa和BbCc

3 特殊条件
Page<User> findByLastname(String lastname, Pageable pageable);
Slice<User> findByLastname(String lastname, Pageable pageable);
List<User> findByLastname(String lastname, Sort sort);
List<User> findByLastname(String lastname, Pageable pageable);
第一个方法允许你传递一个org.springframework.data.domain.Pageable实例到查询方法来动态的进行分页。一个Page知道总数量和一共多少页可用。它之所以知道这些是因为底层框架触发了一个技计数查询来计算全部的数量。根据使用的数据存储技术不同这可能消耗很大时间,可以使用Slice来替代它。Slice只知道是否存在下一个Slice可用,这将会非常适合查询超大结果集。
排序操作也可以通过Pageable接口来处理。如果你仅仅需要排序那么可以使用org.springframework.data.domain.Sort实例作为方法参数。如你所见,查询方法也可以仅仅返回一个List。这将约束查询方法只查询给定范围的数据。
来源:https://www.jianshu.com/p/27e1d583aafb 1.4章
  • 使用@query注解进行自定义查询(自定义查询方式一) 注解内为elasticsearch json,格式如下
@Query("{\"bool\" : {\"must\" : {\"match\" : {\"name\" : \"?0\"}}}}")
public List<XxBean> findByNameLike(String name);

根据入参完全匹配name字段查询

  • 使用构造器自定义查询(自定义查询方式二,不在接口内写)
SearchQuery searchQuery = new NativeSearchQueryBuilder()
  .withFilter(regexpQuery("title", ".*data.*"))
  .build();
List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);

查询title字段包含data的数据
  • 分页可在参数中传递PageRequest,深度分页需要scroll、scroll-scan
    repository.findAll(new PageRequest(1, 20))

4 调用接口

package com.coldxiangyu.elasticsearch.service.impl;

import com.coldxiangyu.elasticsearch.bean.QuestionBean;
import com.coldxiangyu.elasticsearch.repository.QuestionRepository;
import com.coldxiangyu.elasticsearch.service.QuestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service("questionService")
public class QuestionServiceImpl implements QuestionService {

    @Autowired
    @Qualifier("questionRepository")
    private QuestionRepository questionRepository;


    @Override
    public Optional<QuestionBean> findById(String id) {
        //CrudRepository中的方法
        return questionRepository.findById(id);
    }

    @Override
    public QuestionBean save(QuestionBean blog) {
        return questionRepository.save(blog);
    }

}

5 相关bean实体

package com.coldxiangyu.elasticsearch.bean;

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

@Document(indexName = "qa_applicant_to_attachment", type = "_doc")
public class ApplicantAttachmentBean {
    @Id
    private String id;
    private String applicantId;
    private String attachmentId;

    public ApplicantAttachmentBean(){}

    public ApplicantAttachmentBean(String id, String applicantId, String attachmentId) {
        this.id = id;
        this.applicantId = applicantId;
        this.attachmentId = attachmentId;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getApplicantId() {
        return applicantId;
    }

    public void setApplicantId(String applicantId) {
        this.applicantId = applicantId;
    }

    public String getAttachmentId() {
        return attachmentId;
    }

    public void setAttachmentId(String attachmentId) {
        this.attachmentId = attachmentId;
    }

    @Override
    public String toString() {
        return "AttachmentBean{" +
                "id='" + id + '\'' +
                ", applicantId='" + applicantId + '\'' +
                ", attachmentId='" + attachmentId + '\'' +
                '}';
    }
}

五 注意点

* 深度分页,页数过多时占用资源,使用scroll(有序)scroll-scan(无序);

* 提示不能以root用户启动

添加用户 xxx为你要添加的用户名
useradd xxx
给xxx用户设置密码
passwd xxx
输入密码
再次输入密码
给xxx用户权限,/ELK/elasticsearch-6.4.0是elasticsearch解压根目录
chown -R xxx /ELK/elasticsearch-6.4.0
切换用户为xxx
su xxx
 
再执行
./bin/elasticsearch
或者后台执行
nohup ./bin/elasticsearch >elasticsearch.out &
即可成功
————————————————
版权声明:本文为CSDN博主「King-Long」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u011095110/article/details/82466299

* 公网访问

修改配置文件config/elasticsearch.yml   network.host: 0.0.0.0

* 与springboot版本

https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.requirements

* es映射类中可用@Field(type=FieldType.nested)嵌套对象,但嵌套对象不能直接操作,增删改需要将整个对象查出,修改后再整个存回去(覆盖回去)。至少2.x文档是这么说的。用put命令可以局部修改,但6.x的Script类参数大改,还没研究出怎么用,就先用了下述方法。

* es增删改

    /*
     * es cud通信示例
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public void saveQuestion2(QaQuestionES questionBean,String qaQuestionESId){
        HashMap<String,Object> params = new HashMap<String,Object>();
        params.put("questionDetail", JSON.toJSON(questionBean.getQuestionDetail()));
        //6.x要用HashMap传参,不能用json。嵌套对象则将value对象转为json,基本类型直接放。
        //修改用prepareUpdate,增加用prepareIndex。三个参数分别为映射类的索引、类型、主键。
        elasticsearchTemplate.getClient().prepareUpdate(ESIndexName,ESTypeName,qaQuestionESId).setDoc(params).get();
    }

    //另一种通信方式
    public void saveQuestion3(QaQuestionES.QuestionBean questionBean,String qaQuestionESId){
        HashMap<String,Object> params = new HashMap<String,Object>();
        UpdateRequest ur = new UpdateRequest();
        ur.index(ESIndexName);
        ur.type(ESTypeName);
        ur.id(qaQuestionESId);
        params.put("applicantTeam","四部");
        ur.doc(params);
        try {
            elasticsearchTemplate.getClient().update(ur).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

* es查询


    public QaQuestionES findByQuestionId(String id){
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //查询条件,嵌套对象下的条件则 父类属性名.字段名
        QueryBuilder queryBuilder = QueryBuilders.matchQuery("questionId", id);
        boolQueryBuilder.must(queryBuilder);
        SearchResponse response = elasticsearchTemplate.getClient().prepareSearch("qa_question").setQuery(boolQueryBuilder).get();
        // 返回搜索结果
        SearchHits hits = response.getHits();
        for (SearchHit searchHit : hits) {
            try {
                QaQuestionES qaQuestionES = objectMapper.readValue(searchHit.getSourceAsString(), QaQuestionES.class);
                return qaQuestionES;
            } catch (Exception e) {
                log.error("结果解析异常{}", e);
            }
        }
        return null;
    }

 

* 注解

  • @Document注解实体类,indexName为索引(对应库),type为类型(对应表)
  • @id用于注解主键
  • @Field注解嵌套的集合属性时,type=FieldType.Nested

F 参考

https://my.oschina.net/wenjinglian/blog/1863361  增删改查方式介绍

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值