=====基础脚本操作
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。