elasticsearch梅开二度之基础学习

=====基础脚本操作
GET user_index

创建索引

PUT person

查询索引

GET person

删除索引

DELETE person

查询映射

GET person/_mapping

添加映射(先创建索引,后单独添加映射)

PUT person/_mapping
{
  "properties":{
    "name":{
      "type":"keyword"
    },
    "age":{
      "type":"integer"
    }
  }
}

创建索引时添加映射

PUT person_index
{
  "mappings": {
    "properties": {
      "name":{
        "type":"keyword"
      },
      "age":{
        "type":"integer"
      }
    }
  }
}

GET person_index

创建好映射关系后添加字段

PUT person_index/_mapping
{
  "properties":{
    "address":{
      "type":"text"
    }
  }
}

添加文档,使用put和post都可以

使用put添加文档需要指定id

PUT person_index/_doc/1
{
  "name":"小白龙",
  "age":18,
  "address":"杭州市西湖名胜风景区"
}

使用post添加文档,id可以指定也可以不指定

POST person_index/_doc/2
{
  "name":"猪八戒",
  "age":20,
  "address":"花果山水帘洞隔壁"
}

根据id可以获取到指定的文档数据

GET person_index/_doc/1

put 操作文档,如果文档不存在,则新增,如果文档存在则修改

PUT person_index/_doc/1
{
  "name":"小白龙",
  "age":18,
  "address":"杭州市西湖名胜风景区旁边狗窝"
}

查询所有的文档

GET person_index/_search

根据id删除文档

DELETE person_index/_doc/AjT50nEB5tV2FsqE6st1

===ik分词

细粒度的分词 分词的力度大

GET _analyze
{
  "analyzer": "ik_max_word"
  ,"text": "我爱中国北京天安门"
}

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "爱",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "中国北京",
      "start_offset" : 2,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "中国",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 3
    },
    {
      "token" : "北京",
      "start_offset" : 4,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 4
    },
    {
      "token" : "天安门",
      "start_offset" : 6,
      "end_offset" : 9,
      "type" : "CN_WORD",
      "position" : 5
    },
    {
      "token" : "天安",
      "start_offset" : 6,
      "end_offset" : 8,
      "type" : "CN_WORD",
      "position" : 6
    },
    {
      "token" : "门",
      "start_offset" : 8,
      "end_offset" : 9,
      "type" : "CN_CHAR",
      "position" : 7
    }
  ]
}

粗粒度的分词 分词的力度小

GET _analyze
{
  "analyzer": "ik_smart"
  ,"text": "我爱中国北京天安门"
}

{
  "tokens" : [
    {
      "token" : "我",
      "start_offset" : 0,
      "end_offset" : 1,
      "type" : "CN_CHAR",
      "position" : 0
    },
    {
      "token" : "爱",
      "start_offset" : 1,
      "end_offset" : 2,
      "type" : "CN_CHAR",
      "position" : 1
    },
    {
      "token" : "中国北京",
      "start_offset" : 2,
      "end_offset" : 6,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "天安门",
      "start_offset" : 6,
      "end_offset" : 9,
      "type" : "CN_WORD",
      "position" : 3
    }
  ]
}

tremquery matchQuery======

GET person_index

GET person_index/_search

创建索引添加映射,指定ik分词器

PUT person_index
{
  "mappings": {
    "properties": {
      "name":{
        "type": "keyword"
      },
      "address":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

PUT person_index/_doc/1
{
  "name":"小白龙",
  "address":"杭州市西湖名胜风景区"
}


POST person_index/_doc/2
{
  "name":"猪八戒",
  "address":"花果山水帘洞隔壁"
}

termQuery 不会对查询的关键字进行分词,直接和词条进行匹配

GET person_index/_search
{
  "query": {
    "term": {
      "address": {
        "value": "花果山水帘洞隔壁"
      }
    }
  }
}

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

matchQuery 会对查询的关键字先进行分词,然后和词条进行匹配

GET person_index/_search
{
  "query": {
    "match": {
      "address": "花果山水帘洞隔壁"
    }
  }
}

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 5.113517,
    "hits" : [
      {
        "_index" : "person_index",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 5.113517,
        "_source" : {
          "name" : "猪八戒",
          "address" : "花果山水帘洞隔壁"
        }
      }
    ]
  }
}

====
===============javaAPI操作索引

package cn.com.youlove.es_demo;

import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.Map;

@SpringBootTest
class EsDemoApplicationTests {

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    @Test
    void contextLoads() {
        System.out.println(restHighLevelClient);
    }

    /**
     * 创建索引
     * @throws IOException
     */
    @Test
    public void addIndex() throws IOException {
        // 1.获取创建索引对象
        IndicesClient indicesClient = restHighLevelClient.indices();

        // 3.构建创建索引库条件
        CreateIndexRequest createRequest = new CreateIndexRequest("student");
        // 2.创建一个索引库
        CreateIndexResponse response = indicesClient.create(createRequest, RequestOptions.DEFAULT);

        boolean acknowledged = response.isAcknowledged();
        System.out.println(acknowledged);

    }

    /**
     * 创建索引并添加映射
     * @throws IOException
     */
    @Test
    public void addIndexAndMapping() throws IOException {
        // 1.获取创建索引对象
        IndicesClient indicesClient = restHighLevelClient.indices();

        // 3.构建创建索引库条件
        CreateIndexRequest createRequest = new CreateIndexRequest("raven");
        String mapping = "{\n" +
                "      \"properties\" : {\n" +
                "        \"address\" : {\n" +
                "          \"type\" : \"text\",\n" +
                "          \"analyzer\" : \"ik_max_word\"\n" +
                "        },\n" +
                "        \"name\" : {\n" +
                "          \"type\" : \"keyword\"\n" +
                "        }\n" +
                "      }\n" +
                "    }";

        createRequest.mapping(mapping, XContentType.JSON);
        // 2.创建一个索引库
        CreateIndexResponse response = indicesClient.create(createRequest, RequestOptions.DEFAULT);

        boolean acknowledged = response.isAcknowledged();
        System.out.println(acknowledged);

    }

    /**
     * 获取索引
     * @throws IOException
     */
    @Test
    public void getIndex() throws IOException {
        IndicesClient indicesClient = restHighLevelClient.indices();
        GetIndexRequest indexCRequest = new GetIndexRequest("raven");
        GetIndexResponse response = indicesClient.get(indexCRequest, RequestOptions.DEFAULT);
        Map<String, MappingMetaData> mappings = response.getMappings();
        mappings.entrySet().forEach(mapping -> System.out.println(mapping.getKey() + ":" + mapping.getValue().getSourceAsMap()));
        mappings.keySet().forEach(key -> System.out.println( key + ":" + mappings.get(key).getSourceAsMap()));
    }

    /**
     * 删除索引
     * @throws IOException
     */
    @Test
    public void delIndex() throws IOException {
        IndicesClient indicesClient = restHighLevelClient.indices();

        DeleteIndexRequest deleteRequest = new DeleteIndexRequest("person_index");
        AcknowledgedResponse response = indicesClient.delete(deleteRequest, RequestOptions.DEFAULT);
        boolean acknowledged = response.isAcknowledged();
        if (acknowledged){
            System.out.println("删除成功");
        }
    }

    /**
     * 判断索引是否存在
     * @throws IOException
     */
    @Test
    public void existIndex() throws IOException {
        IndicesClient indicesClient = restHighLevelClient.indices();

        GetIndexRequest request = new GetIndexRequest("raven");
        boolean exists = indicesClient.exists(request, RequestOptions.DEFAULT);
        if (exists){
            System.out.println("索引存在");
        }
    }
}

javaAPI操作文档-

/**
 * 添加文档,使用map构建数据
 * @throws IOException
 */
@Test
public void addDoc() throws IOException {
    Map<String, Object> map = new HashMap<>();
    map.put("address","陕西西安雁塔区");
    map.put("name","小朋友");
    IndexRequest request = new IndexRequest("raven").id("1").source(map);
    IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
    String id = response.getId();
    System.out.println(id);
    String index = response.getIndex();
    System.out.println(index);
}

/**
 * 添加文档,使用对象构建数据 (修改文档,当id存在则修改,id不存在,则创建)
 * @throws IOException
 */
@Test
public void addDoc2() throws IOException {

    Person person = new Person();
    person.setAddress("浙江杭州西湖美景风景名胜区");
    person.setName("杭州");
    String data = JSON.toJSONString(person);
    IndexRequest request = new IndexRequest("raven").id("2").source(data,XContentType.JSON);
    IndexResponse response = restHighLevelClient.index(request, RequestOptions.DEFAULT);
    String id = response.getId();
    System.out.println(id);
    String index = response.getIndex();
    System.out.println(index);
}

/**
 * 根据id获取文档数据信息
 * @throws IOException
 */
@Test
public void getDoc() throws IOException{

    // 获取请求对象,设置索引库名称,以及文档的id
    GetRequest request = new GetRequest("raven","2");
    GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);
    String sourceAsString = response.getSourceAsString();
    System.out.println(sourceAsString);
}

/**
 * 根据id删除文档数据信息
 * @throws IOException
 */
@Test
public void delDoc() throws IOException{

    // 获取请求对象,设置索引库名称,以及文档的id
    DeleteRequest request = new DeleteRequest("raven","2");
    DeleteResponse response = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
    System.out.println(response.getId());
}

批量操作bluk================

bluk批量操作

添加三号记录,删除2号记录,修改1号记录。

create 需要有指定的data数据,update需要有指定的文档修改标识

POST _bulk
{"create":{"_index":"raven","_id":"3"}}
{"address":"中国北京天安门","name":"大张伟"}
{"delete":{"_index":"raven","_id":"2"}}
{"update":{"_index":"raven","_id":"1"}}
{"doc":{"name":"小朋友性格不好"}}

/**
 * 批量操作文档
 * @throws IOException
 */
@Test
public void bulkDoc() throws IOException{
    // 1.创建批量操作请求对象
    BulkRequest bulkRequest = new BulkRequest();
    // 2.添加相应的操作逻辑

    // 2.1添加3号文档
    Map<String, Object> map = new HashMap<>();
    map.put("address","中国上海陆家嘴");
    map.put("name","陈赫");
    IndexRequest addRequest = new IndexRequest("raven").id("3").source(map);
    bulkRequest.add(addRequest);
    // 2.2.修改2号文档
    Map<String, Object> updateMap = new HashMap<>();
    updateMap.put("address","中国北京朝阳区");
    updateMap.put("name","大张伟");
    UpdateRequest updateRequest = new UpdateRequest("raven","2").doc(updateMap);
    bulkRequest.add(updateRequest);

    // 2.3删除1号文档
    DeleteRequest deleteRequest = new DeleteRequest("raven").id("1");
    bulkRequest.add(deleteRequest);
    // 3. 执行批量操作
    BulkResponse responses = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    boolean flag = responses.hasFailures();
    if (!flag){
        System.out.println("执行完毕,没有发送错误");
    }
}

===批量导入数据准备

PUT goods
{
	"mappings": {
		"properties": {
			"title": {
				"type": "text",
				"analyzer": "ik_smart"
			},
			"price": { 
				"type": "double"
			},
			"createTime": {
				"type": "date"
			},
			"categoryName": {	
				"type": "keyword"
			},
			"brandName": {	
				"type": "keyword"
			},
	
			"spec": {		
				"type": "object"
			},
			"saleNum": {	
				"type": "integer"
			},
			
			"stock": {	
				"type": "integer"
			}
		}
	}
}

POST goods/_doc/1
{
  "title":"小米手机",
  "price":1000,
  "createTime":"2019-12-01",
  "categoryName":"手机",
  "brandName":"小米",
  "saleNum":3000,
  "stock":10000,
  "spec":{
    "网络制式":"移动4G",
    "屏幕尺寸":"4.5"
  }
}


GET goods/_search

package cn.com.youlove.es_demo.domain;

import com.alibaba.fastjson.annotation.JSONField;

import java.util.Date;
import java.util.Map;

public class Goods {

    private int id;
    private String title;
    private double price;
    private int stock;
    private int saleNum;
    private Date createTime;
    private String categoryName;
    private String brandName;
    private Map spec;

    @JSONField(serialize = false)//在转换JSON时,忽略该字段
    private String specStr;//接收数据库的信息 "{}"


    public int getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getStock() {
        return stock;
    }

    public void setStock(int stock) {
        this.stock = stock;
    }

    public int getSaleNum() {
        return saleNum;
    }

    public void setSaleNum(int saleNum) {
        this.saleNum = saleNum;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public Map getSpec() {
        return spec;
    }

    public void setSpec(Map spec) {
        this.spec = spec;
    }

    public String getSpecStr() {
        return specStr;
    }

    public void setSpecStr(String specStr) {
        this.specStr = specStr;
    }


    @Override
    public String toString() {
        return "Goods{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", price=" + price +
                ", stock=" + stock +
                ", saleNum=" + saleNum +
                ", createTime=" + createTime +
                ", categoryName='" + categoryName + '\'' +
                ", brandName='" + brandName + '\'' +
                ", spec=" + spec +
                ", specStr='" + specStr + '\'' +
                '}';
    }
}

yml:

# datasource
spring:
  datasource:
    url: jdbc:mysql:///raven?serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver


# mybatis
mybatis:
  mapper-locations: classpath:mapper/*Mapper.xml # mapper映射文件路径
  type-aliases-package: cn.com.youlove.es_demo.domain
  pom.xml
  <!--mybatis-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

=javaAPI批量导入测试数据

mapper 接口
findAll
@Autowired
private GoodsMapper goodsMapper;

/**
 * 批量导入数据
 */
@Test
public void importData() throws IOException {
    // 1.查询获取到所有的数据
    List<Goods> goodsList = goodsMapper.findAll();
    // 2.构建bulk请求对象
    BulkRequest bulkRequest = new BulkRequest();
    goodsList.forEach(goods -> {
        // 2.1设置spec规格信息 map格式
        goods.setSpec(JSONObject.parseObject(goods.getSpecStr(),Map.class));
        // 2.2 将添加文档的操作加入到请求对象中
        // 指定索引库名称 指定id 指定添加文档参数的类型为json
        IndexRequest addRequest = new IndexRequest("goods").id(String.valueOf(goods.getId())).source(JSON.toJSONString(goods),XContentType.JSON);
        bulkRequest.add(addRequest);
    });

    // 3.执行批量操作
    BulkResponse response = restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    if (!response.hasFailures()){
        System.out.println("执行完毕,没有发送错误");
    }
}

查询脚本及API======

match all

默认情况下 es 每次展示10条数据

match all 查询所有数据 from size 用来控制分页

GET goods/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 100
}
/**
 *
 * 查询所有数据 指定展示50条数据
 * @throws IOException
 */
@Test
public void matchAllTest() throws IOException{

    // 2.创建查询请求
    SearchRequest searchRequest = new SearchRequest("goods");
    // 5.创建一个查询对象
    QueryBuilder query = QueryBuilders.matchAllQuery();
    // 4.创建一个查询构造器
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query).from(0).size(50);
    // 3.使用查询构造器查询
    searchRequest.source(sourceBuilder);
    // 1.进行查询操作
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);

    ArrayList<Goods> list = Lists.newArrayList();
    SearchHit[] hits = searchResponse.getHits().getHits();
    System.out.println("命中数据总数为:" + searchResponse.getHits().getTotalHits().value);
    for (SearchHit hit : hits) {
        String sourceAsString = hit.getSourceAsString();
        Goods goods = JSONObject.parseObject(sourceAsString, Goods.class);
        list.add(goods);
    }
    list.forEach(System.out::println);
}

term 查询

term 查询

GET goods/_search
{
  "query": {
    "term": {
      "categoryName": {
        "value": "手机"
      }
    }
  }
  , "from": 0
  , "size": 20
}
/**
 * term查询
 * @throws IOException
 */
@Test
public void termQuery() throws IOException{

    // 2.构建查询请求对象
    SearchRequest searchRequest = new SearchRequest("goods");
    // 5.封装查询条件
    QueryBuilder query = QueryBuilders.termQuery("categoryName","手机");
    // 4.创建查询请求构建器
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query).from(0).size(10);
    // 3.装载查询请求构建器
    searchRequest.source(sourceBuilder);
    // 1.进行查询请求
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    long value = searchResponse.getHits().getTotalHits().value;
    System.out.println("类型为手机的数据共有:" + value + "个");
    ArrayList<Goods> list = Lists.newArrayList();
    SearchHit[] hits = searchResponse.getHits().getHits();
    for (SearchHit hit : hits) {
        String sourceAsString = hit.getSourceAsString();
        Goods goods = JSONObject.parseObject(sourceAsString, Goods.class);
        list.add(goods);
    }
    list.forEach(System.out::println);
}

match 查询

查询所有符合条件词条,关键字会进行分词 默认取分词的并集

GET goods/_search
{
  "query": {
    "match": {
      "title": "三星手机"
    }
  }
}

查询所有符合条件的词条,取交集

GET goods/_search
{
  "query": {
    "match": {
      "title": {
        "query": "三星手机",
        "operator": "and"
      }
    }
  }
}
/**
 * matchQuery 分词查询
 * @throws IOException
 */
@Test
public void matchQuery() throws IOException{

    // 2.构建查询请求对象
    SearchRequest searchRequest = new SearchRequest("goods");
    // 5.封装查询条件
    QueryBuilder query = QueryBuilders.matchQuery("title","三星手机").operator(Operator.AND);
    // 4.创建查询请求构建器
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query).from(0).size(10);
    // 3.装载查询请求构建器
    searchRequest.source(sourceBuilder);
    // 1.进行查询请求
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    long value = searchResponse.getHits().getTotalHits().value;
    System.out.println("title为三星手机的数据共有:" + value + "个");
    ArrayList<Goods> list = Lists.newArrayList();
    SearchHit[] hits = searchResponse.getHits().getHits();
    for (SearchHit hit : hits) {
        String sourceAsString = hit.getSourceAsString();
        Goods goods = JSONObject.parseObject(sourceAsString, Goods.class);
        list.add(goods);
    }
    list.forEach(System.out::println);
}

模糊查询 ?代表一个 *代表一个或多个

GET goods/_search
{
  "query": {
    "wildcard": {
      "title": {
        "value": "华为*"
      }
    }
  }
}

正则查询

GET goods/_search
{
  "query": {
    "regexp": {
      "title": "\\w+(.)*"
    }
  }
}

前缀查询

GET goods/_search
{
  "query": {
    "prefix": {
      "brandName": {
        "value": "三星"
      }
    }
  }
}

/**
 * wildcardQuery // regexp prefix 将QueryBuilders 后跟随的查询换为正则或前缀查询即可
 * @throws IOException
 */
@Test
public void wildcardQuery() throws IOException{

    // 2.构建查询请求对象
    SearchRequest searchRequest = new SearchRequest("goods");
    // 5.封装查询条件
    QueryBuilder query = QueryBuilders.wildcardQuery("title","三星*");
    // 4.创建查询请求构建器
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query).from(0).size(10);
    // 3.装载查询请求构建器
    searchRequest.source(sourceBuilder);
    // 1.进行查询请求
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    long value = searchResponse.getHits().getTotalHits().value;
    System.out.println("title为三星手机的数据共有:" + value + "个");
    ArrayList<Goods> list = Lists.newArrayList();
    SearchHit[] hits = searchResponse.getHits().getHits();
    for (SearchHit hit : hits) {
        String sourceAsString = hit.getSourceAsString();
        Goods goods = JSONObject.parseObject(sourceAsString, Goods.class);
        list.add(goods);
    }
    list.forEach(System.out::println);
}
范围查询

范围查询,查询后进行排序,默认的排序方式为降序排序

指定排序方式为升序,并将数据进行分页

GET goods/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 1000,
        "lte": 2000
      }
    }
  },
  "sort": [
    {
      "price": {
        "order": "asc"
      }
    }
  ],
  "from": 0
  , "size": 50
}

/**
 * 范围查询,查询1000-2000内的手机 并进行排序
 *
 * @throws IOException
 */
@Test
public void rangeQueryAndSortQuery() throws IOException {

    // 2.构建查询请求,指定索引库
    SearchRequest searchRequest = new SearchRequest("goods");
    // 5.创建查询
    QueryBuilder query = QueryBuilders.rangeQuery("price").gte(1000).lte(2000);
    // 4.创建查询构建器,指定查询
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query).from(0).size(50).sort("price", SortOrder.ASC);
    // 3.指定查询构建器
    searchRequest.source(sourceBuilder);
    // 1.执行搜索
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    // 5.将结果进行处理
    SearchHits searchHits = searchResponse.getHits();
    long value = searchHits.getTotalHits().value;
    System.out.println("符合条件的数据共有:" + value + "条");
    // 6.将结果封装到对象中
    ArrayList<Goods> list = Lists.newArrayList();
    for (SearchHit hit : searchHits.getHits()) {
        Goods goods = JSONObject.parseObject(hit.getSourceAsString(), Goods.class);
        list.add(goods);
    }
    list.forEach(System.out::println);
}

queryStringQuery 支持分词后对多字段进行匹配的查询方式

默认取并集 OR 可以指定为AND

GET goods/_search
{
  "query": {
    "query_string": {
      "fields": ["categoryName","brandName","title"],
      "query": "三星 OR 手机"
    }
  }
}

simpleQueryQuery和queryString相比较不支持查询条件中书写AND 只能进行取并集的查询

GET goods/_search
{
  "query": {
    "simple_query_string": {
      "fields": ["categoryName","brandName","title"],
      "query": "三星 AND 手机"
    }
  }
}

/**
 * queryStringQuery  QueryStringQueryBuilder里面书写查询条件,后面跟随指定的字段,可以指定多个字段
 *
 * @throws IOException
 */
@Test
public void queryStringQuery() throws IOException {

    // 2.构建查询请求,指定索引库
    SearchRequest searchRequest = new SearchRequest("goods");
    // 5.设置查询条件
    QueryStringQueryBuilder query= new QueryStringQueryBuilder("三星 AND 手机").field("categoryName").field("brandName").field("title");
    // 4.创建查询构建器
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query);
    // 3.指定查询构建器
    searchRequest.source(sourceBuilder);
    // 1.执行搜索
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    // 6.将结果进行处理
    SearchHits searchHits = searchResponse.getHits();
    long value = searchHits.getTotalHits().value;
    System.out.println("符合条件的数据共有:" + value + "条");
    // 7.将结果封装到对象中
    ArrayList<Goods> list = Lists.newArrayList();
    for (SearchHit hit : searchHits.getHits()) {
        Goods goods = JSONObject.parseObject(hit.getSourceAsString(), Goods.class);
        list.add(goods);
    }
    list.forEach(System.out::println);
}
bool多条件查询

boolquery可以将多个查询条件拼接起来

支持 must(and) must_not(no) should(or) filter

must 计算得分 效率低于filter

查询出title中必须包含手机的数据,并且品牌可以为三星 也可以为华为的

GET goods/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "title": {
              "value": "手机"
            }
          }
        }
      ,{
        "bool": {
          "should": [
            {
              "term": {
                "brandName": {
                  "value": "三星"
                }
              }
            }
            ,{
              "term": {
                "brandName": {
                  "value": "华为"
                }
              }
            }
          ]
        }
      }
      ]
    }
  },
  "from": 0
  , "size": 193
}

/**
 * 布尔查询 可以将多个不同的查询组合起来
 * 查询出title中必须包含手机的数据,并且品牌可以为三星 也可以为华为的
 * @throws IOException
 */
@Test
public void boolQuery() throws IOException{
    // 2.创建查询请求,指定索引库
    SearchRequest searchRequest = new SearchRequest("goods");
    // 5.创建查询条件boolQuery
    BoolQueryBuilder query = QueryBuilders.boolQuery();
    // 5.1指定title中必须包含手机
    QueryBuilder termQuery = QueryBuilders.termQuery("title","手机");
    query.must(termQuery);

    // 5.2构建一个新的boolQuery在 boolQuery内
    BoolQueryBuilder newQuery = QueryBuilders.boolQuery();
    // 5.2.1将品牌为三星的termQuery放到新的boolQuery中
    TermQueryBuilder sXTerm = QueryBuilders.termQuery("brandName", "三星");
    newQuery.should(sXTerm);
    // 5.2.2将品牌为华为的termQuery放到新的boolQuery中
    TermQueryBuilder hWTerm = QueryBuilders.termQuery("brandName", "华为");
    newQuery.should(hWTerm);
    // 5.3 将新的boolQuery放到query中
    query.must(newQuery);
    // 4.创建查询构建器
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query);

    // 3.将构建器加载到查询请求中
    searchRequest.source(sourceBuilder);
    // 1.执行查询请求
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    // 6.将结果进行处理
    SearchHits searchHits = searchResponse.getHits();
    long value = searchHits.getTotalHits().value;
    System.out.println("符合条件的数据共有:" + value + "条");
    // 7.将结果封装到对象中
    ArrayList<Goods> list = Lists.newArrayList();
    for (SearchHit hit : searchHits.getHits()) {
        Goods goods = JSONObject.parseObject(hit.getSourceAsString(), Goods.class);
        list.add(goods);
    }
    list.forEach(System.out::println);
}

聚合查询在es中分为指标聚合(聚合函数) + 桶聚合(分组)

指标聚合

GET goods/_search
{
  "query": {
    "match": {
      "title": "手机"
    }
  },
  "aggs": {
    "max_price": {
      "max": {
        "field": "price"
      }
    }
  }
}

桶聚合,手机品牌进行分组

GET goods/_search
{
  "query": {
    "match": {
      "title": "手机"
    }
  }
  , "aggs": {
    "brandName_Type": {
      "terms": {
        "field": "brandName",
        "size": 100
      }
    }
  }
}

/**
 * 聚合查询 分为指标聚合(聚合函数) 桶集合(分组查询)
 * 处理返回结果的聚合函数的值时, 需要使用相对应的Max min 等接口接收结果,然后返回值
 * @throws IOException
 */
@Test
public void aggsQuery() throws IOException{
    // 2.创建查询请求,指定索引库
    SearchRequest searchRequest = new SearchRequest("goods");
    // 5.创建查询条件Query
    QueryBuilder query = QueryBuilders.matchQuery("title","手机");
    // 5.1 计算出价格最贵的手机
    AggregationBuilder aggs = AggregationBuilders.max("max_price").field("price");
    // 4.创建查询构建器
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query).aggregation(aggs);

    // 3.将构建器加载到查询请求中
    searchRequest.source(sourceBuilder);
    // 1.执行查询请求
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    // 6.将结果进行处理
    SearchHits searchHits = searchResponse.getHits();
    long value = searchHits.getTotalHits().value;
    System.out.println("符合条件的数据共有:" + value + "条");
    // 6.2 对聚合函数中的结果进行处理
    Max max_price = searchResponse.getAggregations().get("max_price");
    System.out.println(max_price.getValue());
    // 7.将结果封装到对象中
    ArrayList<Goods> list = Lists.newArrayList();
    for (SearchHit hit : searchHits.getHits()) {
        Goods goods = JSONObject.parseObject(hit.getSourceAsString(), Goods.class);
        list.add(goods);
    }
    list.forEach(System.out::println);
}

/**
 * 分组查询
 * @throws IOException
 */
@Test
public void aggsGroopQuery() throws IOException{
    // 2.创建查询请求,指定索引库
    SearchRequest searchRequest = new SearchRequest("goods");
    // 5.创建查询条件Query
    QueryBuilder query = QueryBuilders.matchQuery("title","手机");
    // 5.1 计算出价格最贵的手机
    AggregationBuilder aggs = AggregationBuilders.terms("brandName_Type").field("brandName").size(100);
    // 4.创建查询构建器
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query).aggregation(aggs);

    // 3.将构建器加载到查询请求中
    searchRequest.source(sourceBuilder);
    // 1.执行查询请求
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    // 6.将结果进行处理
    SearchHits searchHits = searchResponse.getHits();
    long value = searchHits.getTotalHits().value;
    System.out.println("符合条件的数据共有:" + value + "条");
    // 6.2 对聚合函数中的结果进行处理
    Terms brandName_type = (Terms) searchResponse.getAggregations().asMap().get("brandName_Type");
    // 6.3输出所有的品牌
    brandName_type.getBuckets().stream().map(Terms.Bucket::getKey).collect(Collectors.toList()).forEach(System.out::println);
    // 7.将结果封装到对象中
    ArrayList<Goods> list = Lists.newArrayList();
    for (SearchHit hit : searchHits.getHits()) {
        Goods goods = JSONObject.parseObject(hit.getSourceAsString(), Goods.class);
        list.add(goods);
    }
    list.forEach(System.out::println);
}

###高亮查询

高亮查询 三要素 设置前缀 设置后缀 替换高亮内容

GET goods/_search
{
  "query": {
    "match": {
      "title": "电视"
    }
  }
  , "highlight": {
    "fields": {
      "title": {
        "pre_tags": "<font color='red'>"
        , "post_tags": "</font>"
      }
    }
  }
}

/**
 * 高亮查询三要素 设置需要高亮查询的字段 设置前缀 设置后缀 最后将数据进行替换
 * @throws IOException
 */
@Test
public void highlightQuery() throws IOException{
    // 2.设置查询的请求对象并设置查询的索引库
    SearchRequest searchRequest = new SearchRequest("goods");
    // 5.设置查询
    QueryBuilder query = QueryBuilders.matchQuery("title","电视");
    // 6.设置高亮3要素
    HighlightBuilder highlighter = new HighlightBuilder().field("title").preTags("<font color = 'red'>").postTags("</font>");
    // 4.创建一个查询构建器 并设置查询条件以及高亮条件
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query).highlighter(highlighter);
    // 3.将加载查询构建器
    searchRequest.source(sourceBuilder);
    // 1.进行查询
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    // 7.获取数据对象
    SearchHit[] searchHits = searchResponse.getHits().getHits();
    
    ArrayList<Goods> list = Lists.newArrayList();
    for (SearchHit searchHit : searchHits) {
        // 7.1获取到数据 将数据解析为goods对象
        Goods goods = JSONObject.parseObject(searchHit.getSourceAsString(), Goods.class);
        // 7.2获取到高亮的结果集
        Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
        // 7.3获取到指定的高亮字段
        HighlightField title = highlightFields.get("title");
        // 7.4将高亮字段设置到数据中
        Text[] fragments = title.getFragments();
        goods.setTitle(fragments[0].toString());
        // 7.5将数据封装到集合中
        list.add(goods);
    }
    // 8.输出数据
    list.forEach(System.out::println);
}


# 判断文档是否存在 可以根据状态码head 进行判断
HEAD goods/_doc/536563

/**
 * 根据id判断文档数据信息是否存在
 *
 * @throws IOException
 */
@Test
public void getDoc() throws IOException {

    // 获取请求对象,设置索引库名称,以及文档的id
    GetRequest request = new GetRequest("raven", "2");
    boolean b = restHighLevelClient.existsSource(request, RequestOptions.DEFAULT);
    System.out.println("文档是否存在:"  + b);
}


###
# 可以通过 post 请求_mget 批量的获取到多个数据的集合 如果数据不存在,则不显示
POST goods/_mget
{
  "ids":["1","536563"]
}


/**
 * 设置多个id 一次性获取他们所对应的结果集合
 * 可以获取不同索引库的数据结果
 * @throws IOException
 */
@Test
public void mGetTest() throws IOException {
    // 2.指定不同的索引库中不同id的数据 一次性获取
    MultiGetRequest multigetRequest = new MultiGetRequest().add("goods","1").add("raven","5");
    // 1.这些查询请求
    MultiGetResponse multiGetResponse = restHighLevelClient.mget(multigetRequest, RequestOptions.DEFAULT);
    ArrayList<Goods> goodsList = Lists.newArrayList();
    Map<String, Object> ravenMap = Maps.newHashMap(null,null);
    // 3.处理响应结果
    for (MultiGetItemResponse response : multiGetResponse.getResponses()) {
        if ("goods".equals(response.getIndex())){
            Goods goods = JSONObject.parseObject(response.getResponse().getSourceAsString(), Goods.class);
            goodsList.add(goods);
        }else {
            ravenMap = response.getResponse().getSourceAsMap();
        }

    }
    goodsList.forEach(System.out::println);
    Map<String, Object> finalRavenMap = ravenMap;
    finalRavenMap.keySet().forEach(k -> {
        assert finalRavenMap != null;
        System.out.println( k + "==>" + finalRavenMap.get(k));
    });
}

terms 查询 查询的时候可以匹配 指定字段的多个关键词 进行查询匹配

GET goods/_search
{
  "query": {
    "terms": {
      "title": [
        "华为",
        "电视"
      ]
    }
  }
}
/**
 * terms查询,一个字段多个词条进行匹配
 * @throws IOException
 */
@Test
public void termsQuery() throws IOException{
    SearchRequest searchRequest = new SearchRequest("goods");
    QueryBuilder query = QueryBuilders.termsQuery("title","华为","电视");
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().query(query);
    searchRequest.source(sourceBuilder);
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    long value = searchResponse.getHits().getTotalHits().value;
    System.out.println("共"+ value + "条数据");
}


**

goods的数据sql可以私信我要。

**

bool注意事项:一个"bool":{}中也不能在相同层级出现多个should或must。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值