springboot操作ES之ElasticSearch_EasyEs

这篇具有很好参考价值的文章主要介绍了springboot操作ES之ElasticSearch_EasyEs。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

springboot操作ES之ElasticSearch_EasyEs

前置环境
  • es:7.x
  • springboot:2.6.0
  • easyes:1.0.2
1.导入依赖
   <dependency>
            <groupId>cn.easy-es</groupId>
            <artifactId>easy-es-boot-starter</artifactId>
            <version>1.0.2</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.14.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.14.0</version>
        </dependency>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
2.配置文件
easy-es:
  keep-alive-millis: 18000 # 心跳策略时间 单位:ms
  connectTimeout: 5000 # 连接超时时间 单位:ms
  socketTimeout: 5000 # 通信超时时间 单位:ms
  connectionRequestTimeout: 5000 # 连接请求超时时间 单位:ms
  maxConnTotal: 100 # 最大连接数 单位:个
  maxConnPerRoute: 100 # 最大连接路由数 单位:个
  enable: true # 是否开启EE自动配置
  address: 192.xxxx:9200 # es连接地址+端口 格式必须为ip:port,如果是集群则可用逗号隔开
  schema: http # 默认为http
  username: elastic #如果无账号密码则可不配置此行
  password: 1111111111#如果无账号密码则可不配置此行
  global-config:
    process_index_mode: smoothly #索引处理模式,smoothly:平滑模式,默认开启此模式, not_smoothly:非平滑模式, manual:手动模式
    print-dsl: true # 开启控制台打印通过本框架生成的DSL语句,默认为开启,测试稳定后的生产环境建议关闭,以提升少量性能
    distributed: false # 当前项目是否分布式项目,默认为true,在非手动托管索引模式下,若为分布式项目则会获取分布式锁,非分布式项目只需synchronized锁.
    asyncProcessIndexBlocking: true # 异步处理索引是否阻塞主线程 默认阻塞 数据量过大时调整为非阻塞异步进行 项目启动更快
    activeReleaseIndexMaxRetry: 60 # 分布式环境下,平滑模式,当前客户端激活最新索引最大重试次数若数据量过大,重建索引数据迁移时间超过60*(180/60)=180分钟时,可调大此参数值,此参数值决定最大重试次数,超出此次数后仍未成功,则终止重试并记录异常日志
    activeReleaseIndexFixedDelay: 180 # 分布式环境下,平滑模式,当前客户端激活最新索引最大重试次数 若数据量过大,重建索引数据迁移时间超过60*(180/60)=180分钟时,可调大此参数值 此参数值决定多久重试一次 单位:秒


    db-config:
      map-underscore-to-camel-case: false # 是否开启下划线转驼峰 默认为false
      table-prefix: daily_ # 索引前缀,可用于区分环境  默认为空 用法和MP一样
#      id-type: customize # id生成策略 customize为自定义,id值由用户生成,比如取MySQL中的数据id,如缺省此项配置,则id默认策略为es自动生成
      field-strategy: not_empty # 字段更新策略 默认为not_null
      enable-track-total-hits: true # 默认开启,查询若指定了size超过1w条时也会自动开启,开启后查询所有匹配数据,若不开启,会导致无法获取数据总条数,其它功能不受影响.
      refresh-policy: immediate # 数据刷新策略,默认为不刷新
      enable-must2-filter: false # 是否全局开启must查询类型转换为filter查询类型 默认为false不转换
3.新建实体类

Document

package com.easyes.entity;
import cn.easyes.annotation.HighLight;
import cn.easyes.annotation.IndexField;
import cn.easyes.annotation.IndexId;
import cn.easyes.annotation.IndexName;
import cn.easyes.common.constants.Analyzer;
import cn.easyes.common.enums.FieldStrategy;
import cn.easyes.common.enums.FieldType;
import cn.easyes.common.enums.IdType;
import cn.easyes.common.params.JoinField;
import lombok.Data;
import java.util.List;

/**
 * @Author: Chenyw
 * @Date: 2022/10/24/10:14
 */
@Data
@IndexName(value = "document",shardsNum = 3,replicasNum = 2,childClass = Comment.class)
public class Document {
    /**
     * es中的唯一id,如果你想自定义es中的id为你提供的id,比如MySQL中的id,请将注解中的type指定为customize,如此id便支持任意数据类型)
     */
    @IndexId(type = IdType.NONE)
    private String id;

    /**
     * 文档标题,不指定类型默认被创建为keyword类型,可进行精确查询
     */
    private String title;

    /**
     * 文档内容,指定了类型及存储/查询分词器
     */
    @HighLight(mappingField = "highlightContent")
    @IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART, searchAnalyzer = Analyzer.IK_MAX_WORD)
    private String content;

    /**
     * 作者 加@TableField注解,并指明strategy = FieldStrategy.NOT_EMPTY 表示更新的时候的策略为 创建者不为空字符串时才更新
     */
    @IndexField(strategy = FieldStrategy.NOT_EMPTY)
    private String creator;

    /**
     * 创建时间
     */
    @IndexField(fieldType = FieldType.DATE, dateFormat = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
    private String gmtCreate;

    /**
     * es中实际不存在的字段,但模型中加了,为了不和es映射,可以在此类型字段上加上 注解@TableField,并指明exist=false
     */
    @IndexField(exist = false)
    private String notExistsField;

    /**
     * 地理位置经纬度坐标 例如: "40.13933715136454,116.63441990026217"
     */
    @IndexField(fieldType = FieldType.GEO_POINT)
    private String location;

    /**
     * 图形(例如圆心,矩形)
     */
    @IndexField(fieldType = FieldType.GEO_SHAPE)
    private String geoLocation;

    /**
     * 自定义字段名称
     */
    @IndexField(value = "wu-la")
    private String customField;

    /**
     * 高亮返回值被映射的字段
     */
    private String highlightContent;

    /**
     * 嵌套类型
     */
    @IndexField(fieldType = FieldType.NESTED, nestedClass = User.class)
    private List<User> users;

    /**
     * 须通过注解在父文档及子文档的实体类中指明其类型为Join,及其父名称和子名称,这里的JoinField类框架已内置,无需重复造轮子
     * JoinField类全路径为cn.easyes.common.params.JoinField,如果你非要自己造轮子,也支持,那么需要在@TableField注解中指明joinFieldClass=你造的轮子
     */
    @IndexField(fieldType = FieldType.JOIN, parentName = "document", childName = "comment")
    private JoinField joinField;
}

Comment

package com.easyes.entity;

import cn.easyes.annotation.IndexField;
import cn.easyes.annotation.IndexName;
import cn.easyes.common.enums.FieldType;
import cn.easyes.common.params.JoinField;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @Author: Chenyw
 * @Date: 2022/10/24/15:43
 */
@IndexName(child = true)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Comment {
    /**
     * 父子关系字段 须通过注解在父文档及子文档的实体类中指明其类型为Join,子文档中的父子关系可省略
     */
    @IndexField(fieldType = FieldType.JOIN)
    private JoinField joinField;

    private String id;
    private String commentContent;
}

User文章来源地址https://www.toymoban.com/news/detail-519240.html

package com.easyes.entity;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * @Author: Chenyw
 * @Date: 2022/10/24/15:26
 */
@Data
@AllArgsConstructor
public class User {
    private String username;
    private String password;
}
4.启动类上面加EsMapperScan
package com.easyes;

import cn.easyes.starter.register.EsMapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EsMapperScan("com.easyes.mapper")
public class EasyesApplication {

    public static void main(String[] args) {
        SpringApplication.run(EasyesApplication.class, args);
    }

}
5.最后测试各种操作
package com.easyes;

import cn.easyes.common.params.JoinField;
import cn.easyes.core.biz.PageInfo;
import cn.easyes.core.conditions.LambdaEsQueryWrapper;
import cn.easyes.core.conditions.LambdaEsUpdateWrapper;
import cn.easyes.core.toolkit.FieldUtils;
import com.easyes.entity.Comment;
import com.easyes.entity.Document;
import com.easyes.entity.User;
import com.easyes.mapper.CommentMapper;
import com.easyes.mapper.DocumentMapper;

import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.ShapeRelation;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.geometry.Circle;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
class EasyesApplicationTests {

    @Autowired
    private DocumentMapper documentMapper;

    @Autowired
    private CommentMapper commentMapper;
    @Test
    void createIndex() {
        // 初始化-> 创建索引,相当于MySQL建表 | 此接口须首先调用,只调用一次即可
//        documentMapper.createIndex();
    }

    @Test
    void insert() {
        // 初始化-> 新增数据
        Document document = new Document();
        document.setTitle("嵌套查询");
        document.setContent("这是一条内容");
        document.setCreator("二叔");
        document.setGmtCreate("2022-10-24 00:00:00");

        List<User> list = new ArrayList<>();
        User user1 = new User("陈彦伟", "123456");
        User user2 = new User("二叔", "654321");
        list.add(user1);
        list.add(user2);
        document.setUsers(list);
        documentMapper.insert(document);
    }

    @Test
    void searchWrapper() {
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        /**
         * 匹配查询
         */
        wrapper.eq(Document::getTitle, "嵌套查询");

        /**
         * 分词查询
         */
        wrapper.match(Document::getContent, "内容");
        List<Document> documents = documentMapper.selectList(wrapper);
        documents.forEach(System.out::println);

    }

    @Test
    void searchPage() {
        /**
         * 分页查询
         */
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.eq(Document::getTitle, "嵌套查询");
        PageInfo<Document> documentPageInfo = documentMapper.pageQuery(wrapper, 1, 10);
        System.out.println(documentPageInfo);

    }

    @Test
    void testNestedMatch() {
        // 嵌套查询 查询内容匹配人才且嵌套数据中用户名匹配"用户1"的数据
        // 其中嵌套类的字段名称获取我们提供了工具类FieldUtils.val帮助用户通过lambda函数式获取字段名称,当然如果不想用也可以直接传字符串
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.match(Document::getContent,"内容");
        wrapper.nestedMatch(Document::getUsers, FieldUtils.val(User::getUsername), "二叔");
        System.out.println(documentMapper.selectList(wrapper));
    }


    /**
     * join
     */
    @Test
    void testInsert() {
        // 测试新增父子文档,此处开启自动挡模式,父子类型索引已被自动处理
        // 新新增父文档,然后再插入子文档
        Document document = new Document();
        document.setId("1");
        document.setTitle("父文档的标题");
        document.setContent("父文档的内容");
        JoinField joinField = new JoinField();
        joinField.setName("document");
        document.setJoinField(joinField);
        documentMapper.insert(document);



        // 这里特别注意,子文档必须指定其父文档的id,否则找不到父文档别怪我没提醒
        joinField.setParent("1");
        joinField.setName("comment");


        // 插入子文档
        Comment comment = new Comment();
        comment.setId("2");
        comment.setCommentContent("文档的评论1");
        comment.setJoinField(joinField);
        commentMapper.insert(comment);

        // 插入子文档2
        Comment comment1 = new Comment();
        comment1.setId("3");
        comment1.setCommentContent("文档的评论2");
        comment1.setJoinField(joinField);
        commentMapper.insert(comment1);
    }

    @Test
    void testSelect() {
        // 温馨提示,下面wrapper中的type实际上就是JoinField字段注解@TableField中指定的parentName和childName,与原生语法是一致的
        // case1: hasChild查询,返回的是相关的父文档 所以查询用父文档实体及其mapper
        LambdaEsQueryWrapper<Document> documentWrapper = new LambdaEsQueryWrapper<>();
        documentWrapper.hasChild("comment", FieldUtils.val(Comment::getCommentContent), "评论");
        List<Document> documents = documentMapper.selectList(documentWrapper);
        System.out.println(documents);

        // case2: hasParent查询,返回的是相关的子文档 所以查询用子文档实体及其mapper
        LambdaEsQueryWrapper<Comment> commentWrapper = new LambdaEsQueryWrapper<>();
        // 字段名称你也可以不用FieldUtils.val,直接传入字符串也行
        commentWrapper.hasParent("document", "content", "内容");
        List<Comment> comments = commentMapper.selectList(commentWrapper);
        System.out.println(comments);
//
        // case3: parentId查询,返回的是相关的子文档,与case2类似,所以查询用子文档实体及其mapper
        commentWrapper = new LambdaEsQueryWrapper<>();
        commentWrapper.parentId("1", "comment");
        List<Comment> commentList = commentMapper.selectList(commentWrapper);
        System.out.println(commentList);
    }

    @Test
    void testUpdate() {
        // case1: 父文档/子文档 根据各自的id更新
        Document document = new Document();
        document.setId("1");
        document.setTitle("父标题");
        documentMapper.updateById(document);

        // case2: 父文档/子文档 根据各自条件更新
        Comment comment = new Comment();
        comment.setCommentContent("更新后的评论");
        LambdaEsUpdateWrapper<Comment> wrapper = new LambdaEsUpdateWrapper<>();
        wrapper.match(Comment::getCommentContent, "评论");
        commentMapper.update(comment, wrapper);
    }

    @Test
    void testDelete() {
        // case1: 父文档/子文档 根据各自的id删除
        documentMapper.deleteById("1");

        //case2: 父文档/子文档 根据各自条件删除
        LambdaEsQueryWrapper<Comment> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.match(Comment::getCommentContent, "评论");
        commentMapper.delete(wrapper);
    }

    /**
     * 排序
     */
    @Test
    void testSort(){
        // 测试排序 为了测试排序,我们在Document对象中新增了创建时间字段,更新了索引,并新增了两条数据
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.likeRight(Document::getContent,"这");
        wrapper.select(Document::getTitle,Document::getGmtCreate);
        List<Document> before = documentMapper.selectList(wrapper);
        System.out.println("before:"+before);
        wrapper.orderByDesc(Document::getGmtCreate);
        List<Document> desc = documentMapper.selectList(wrapper);
        System.out.println("desc:"+desc);
    }

    /**
     * 得分排序
     */
    @Test
    void testSortByScore(){
        // 测试根据得分升序排列(分数低的排前面)
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.match(Document::getContent,"这是");
        wrapper.sortByScore(SortOrder.ASC);
        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }
    /**
     * 地图由近及远
     */
    @Test
    void testOrderByDistanceAsc() {
        // 测试给定中心点, 查询出中心点168.8km范围内的数据,并按照距中心点距离由近及远排序
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
        wrapper.match(Document::getCreator, "二叔")
                .geoDistance(Document::getLocation, 168.8, centerPoint)
                .orderByDistanceAsc(Document::getLocation, centerPoint);
        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }

    /**
     * 地图由远及近
     */
    @Test
    void testOrderByDistanceDesc() {
        // 测试给定中心点, 查询出中心点168.8km范围内的数据,并按照距中心点距离由远及近排序
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        GeoPoint centerPoint = new GeoPoint(41.0, 116.0);
        wrapper.match(Document::getCreator, "二叔")
                .geoDistance(Document::getLocation, 168.8, centerPoint)
                .orderByDistanceDesc(Document::getLocation, centerPoint);
        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }
    /**
     * 分组聚合groupBy
     */
    @Test
    void testGroupBy() {
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.groupBy(Document::getCreator);
        // 支持多字段聚合
        // wrapper.groupBy(Document::getCreator,Document::getCreator);
        SearchResponse response = documentMapper.search(wrapper);
        System.out.println(response);
    }
    /**
     * 分词查询
     */
    @Test
    void testMatch(){
        // 会对输入做分词,只要所有分词中有一个词在内容中有匹配就会查询出该数据,无视分词顺序
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.match(Document::getContent,"技术");
        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents.size());
    }

    @Test
    void testMatchPhase() {
        // 会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要求一样,否则就无法查询出结果
        // 例如es中数据是 技术过硬,如果搜索关键词为过硬技术就无法查询出结果
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.matchPhrase(Document::getContent, "技术");
        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }

    @Test
    void testMatchAllQuery() {
        // 查询所有数据,类似mysql select all.
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.matchAllQuery();
        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }

    @Test
    void testMatchPhrasePrefixQuery() {
        // 前缀匹配查询 查询字符串的最后一个词才能当作前缀使用
        // 前缀 可能会匹配成千上万的词,这不仅会消耗很多系统资源,而且结果的用处也不大,所以可以提供入参maxExpansions,若不写则默认为50
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.matchPhrasePrefixQuery(Document::getCustomField, "乌拉巴拉", 10);
        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }

    @Test
    void testMultiMatchQuery() {
        // 从多个指定字段中查询包含老王的数据
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.multiMatchQuery("老王", Document::getTitle, Document::getContent, Document::getCreator, Document::getCustomField);

        // 其中,默认的Operator为OR,默认的minShouldMatch为60% 这两个参数都可以按需调整,我们api是支持的 例如:
        // 其中AND意味着所有搜索的Token都必须被匹配,OR表示只要有一个Token匹配即可. minShouldMatch 80 表示只查询匹配度大于80%的数据
        // wrapper.multiMatchQuery("老王",Operator.AND,80,Document::getCustomField,Document::getContent);

        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents.size());
        System.out.println(documents);
    }

    @Test
    void queryStringQuery() {
        // 从所有字段中查询包含关键词老汉的数据
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.queryStringQuery("内容");
        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }

    @Test
    void prefixQuery() {
        // 查询创建者以"隔壁"打头的所有数据  比如隔壁老王 隔壁老汉 都能被查出来
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        wrapper.prefixQuery(Document::getCreator, "隔壁");
        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }
    /**
     * 地图查询
     * 矩形   原型   无规则
     */
    @Test
    void testGeoBoundingBox() {
        // 查询位于左上点和右下点坐标构成的长方形内的所有点
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        // 假设左上点坐标
        GeoPoint leftTop = new GeoPoint(41.187328D, 115.498353D);
        // 假设右下点坐标
        GeoPoint bottomRight = new GeoPoint(39.084509D, 117.610461D);
        wrapper.geoBoundingBox(Document::getLocation, leftTop, bottomRight);

        // 查不在此长方形内的所有点
//         wrapper.notInGeoBoundingBox(Document::getLocation, leftTop, bottomRight);

        List<Document> documents = documentMapper.selectList(wrapper);
        documents.forEach(System.out::println);
    }

    @Test
    void testGeoDistance() {
        // 查询以经度为41.0,纬度为115.0为圆心,半径168.8公里内的所有点
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        // 其中单位可以省略,默认为km
        wrapper.geoDistance(Document::getLocation, 168.8, DistanceUnit.KILOMETERS, new GeoPoint(41.0, 116.0));

        //查询不在圆形内的所有点
        // wrapper.notInGeoDistance(Document::getLocation, 168.8, DistanceUnit.KILOMETERS, new GeoPoint(41.0, 116.0));

        // 上面语法也可以写成下面这几种形式,效果是一样的,兼容不同用户习惯而已:
//        wrapper.geoDistance(Document::getLocation,"1.5km",new GeoPoint(41.0,115.0));
//        wrapper.geoDistance(Document::getLocation, "1.5km", "41.0,115.0");

        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }

    @Test
    void testGeoPolygon() {
        // 查询以给定点列表构成的不规则图形内的所有点,点数至少为3个
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        List<GeoPoint> geoPoints = new ArrayList<>();
        GeoPoint geoPoint = new GeoPoint(40.178012, 116.577188);
        GeoPoint geoPoint1 = new GeoPoint(40.169329, 116.586315);
        GeoPoint geoPoint2 = new GeoPoint(40.178288, 116.591813);
        geoPoints.add(geoPoint);
        geoPoints.add(geoPoint1);
        geoPoints.add(geoPoint2);
        wrapper.geoPolygon(Document::getLocation, geoPoints);
        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }
    /**
     * 图形由用户自定义(常用),本框架支持Es所有支持的图形:
     * (Point,MultiPoint,Line,MultiLine,Circle,LineaRing,Polygon,MultiPolygon,Rectangle)
     */
    @Test
    public void testGeoShape() {
        // 注意,这里查询的是图形,所以图形的字段索引类型必须为geoShape,不能为geoPoint,故这里用geoLocation字段而非location字段
        LambdaEsQueryWrapper<Document> wrapper = new LambdaEsQueryWrapper<>();
        // 这里以圆形为例演示,其中x,y为圆心坐标,r为半径. 其它图形请读者自行演示,篇幅原因不一一演示了
        Circle circle = new Circle(13,14,100);
        // shapeRelation支持多种,如果不传则默认为within
        wrapper.geoShape(Document::getGeoLocation, circle, ShapeRelation.INTERSECTS);

        // 不符合的情况
        // wrapper.notInGeoShape(Document::getGeoLocation, circle, ShapeRelation.INTERSECTS);

        List<Document> documents = documentMapper.selectList(wrapper);
        System.out.println(documents);
    }
}

到了这里,关于springboot操作ES之ElasticSearch_EasyEs的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Elasticsearch学习笔记五】es常用的JAVA API、es整合SpringBoot项目中使用、利用JAVA代码操作es、RestHighLevelClient客户端对象

    目录 一、Maven项目集成Easticsearch 1)客户端对象 2)索引操作 3)文档操作 4)高级查询 二、springboot项目集成Spring Data操作Elasticsearch 1)pom文件 2)yaml 3)数据实体类 4)配置类 5)Dao数据访问对象 6)索引操作 7)文档操作 8)文档搜索 三、springboot项目集成bboss操作elasticsearch

    2023年04月09日
    浏览(38)
  • 18、全文检索--Elasticsearch-- SpringBoot 整合 Spring Data Elasticsearch(异步方式(Reactive)和 传统同步方式 分别操作ES的代码演示)

    启动命令行窗口,执行:elasticsearch 命令即可启动 Elasticsearch 服务器 三种查询方式解释: 方法名查询: 就是全自动查询,只要按照规则来定义查询方法 ,Spring Data Elasticsearch 就会帮我们生成对应的查询语句,并且生成方法体。 @Query 查询 : 就是半自动查询, 按照 S

    2024年03月12日
    浏览(54)
  • Springboot整合Elasticsearch(Es)

    首先 在测试类中引入RestHighLevelClient对象 其次 准备一个User对象 3.1.1 创建索引  运行结果:创建成功返回true 3.1.2 删除索引 运行结果:删除成功返回true  3.1.3 判断索引是否存在 运行结果:存在返回true,不存在返回false. 3.2.1 添加文档 运行结果:添加成功返回 CREATED 3.2.2 查询文档--

    2023年04月22日
    浏览(33)
  • ElasticSearch系列 - SpringBoot整合ES:ElasticSearch分析器

    1. ElasticSearch match 文本搜索的过程? Elasticsearch 的 match 查询是一种基于文本匹配的查询方式,它的搜索过程如下: ① 将查询字符串分词:Elasticsearch 会将查询字符串分成一个个词项(term),并去除停用词(如“的”、“是”等常用词汇)和标点符号等无意义的字符。 ② 构建

    2023年04月18日
    浏览(113)
  • ElasticSearch基础学习(SpringBoot集成ES)

    一、概述 什么是ElasticSearch? ElasticSearch,简称为ES, ES是一个开源的高扩展的 分布式全文搜索引擎 。 它可以近乎实时的 存储、检索 数据;本身扩展性很好,可以扩展到上百台服务器,处理 PB级别 的数据。 ES也使用 Java 开发并使用 Lucene 作为其核心来实现所有索引和搜索的

    2024年02月13日
    浏览(35)
  • 什么是ES(Elasticsearch)?详解+操作

    elastic:富有弹性的 search:搜索 此软件不再是SpringColud提供的,他也不针对微服务的项目开发 Elasticsearch和Redis/mysqly一样,不仅服务于java开发,其他语言也可以使用 它的功能类似于数据库,能高效的从大量数据中搜索匹配指定的内容 数据保存在硬盘中 Es的底层: 使用了一套名

    2024年02月06日
    浏览(28)
  • Elasticsearch(四)——ES基本操作

    一、Rest风格说明( 非常重要 ) Rest风格一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。 它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。 基于Rest命令说明 method url地址 描述 PUT localh

    2024年02月02日
    浏览(29)
  • elasticSearch集群 springboot集成es 完全解析

    #编写compose.yml配置文件 #每个节点都创建一个elasticsearch.yml文件 用到的命令: systemctl start docker docker-compose up es和kibana版本必须一样 environment:配置容器内的环境变量 networks:创建一个名为elastic的局域网,让各节点以及kibana,es-head相互联系 network.host: 0.0.0.0:意为监听一切地址,可

    2024年02月03日
    浏览(35)
  • 【开发篇】九、SpringBoot整合ES(ElasticSearch)

    整合思路都一样,先起步依赖或普通依赖,再配置,再封装的操作对象。先引入依赖: application.yaml配置: 在需要的地方注入客户端操作对象: 注意 ,与以往不同的是,SpringBoot平台并没有跟随ES的更新速度进行同步更新,ES提供了 High Level Client 操作ES,导入坐标: 不用加配

    2024年02月04日
    浏览(31)
  • elasticsearch(三)-- 理解ES的索引操作

    上一章我们主要学习了es的几个客户端,那么我们后面也主要通过kibana客户端、HighLevelClient高级客户端这两个来学习es. 这一章的学习我们主要是学习一些Elasticsearch的基础操作,主要是深入一些概念,比如索引的具体操作,映射的相关语法,对数据类型,文档的操作。那么主要

    2024年02月04日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包