elasticsearch的使用
elasticsearch的使用
索引管理
1、创建索引
对比关系型数据库,创建索引相当于创建数据库
-
url:
http:/ip:9200/test
-
方式:PUT
不允许重复put相同索引
2、获取索引
a、将请求方式改为get即获取当前索引信息
-
url:
ip:9200/test
-
方式:GET
b、获取所有索引信息
-
url:
ip:9200/_cat/indices?v
-
方式:GET
3、删除索引
将请求方式改为delete即删除当前索引信息
-
url:
ip:9200/test
-
方式:DELETE
文档管理
1、创建文档
-
url:
ip:9200/test/_doc/1001
或者是ip:9200/test/_create/1001
的post请求 -
方式:POST
-
请求体:
{ "title": "小米", "price": 1999 }
若不指定id会自动创建id
2、文档查询
a、主键查询
将请求方式改为get即获取当前文档信息
-
url:
ip:9200/test/_doc/1002
-
方式:GET
b、获取索引中所有文档
-
url:
ip:9200/test/_search
-
方式:GET 请求体必须为空
3、文档修改
a、全部覆盖
-
url:
ip:9200/test/_doc/1001
-
方式:PUT
-
请求体:
{ "title": "小米", "price": 2000 }
b、局部覆盖
-
url:
ip:9200/test/_update/1001
-
方式:POST
-
请求体:
{ "doc":{ "title": "小米", "price": 11 } }
4、文档删除
-
url:
ip:9200/test/_doc/1001
-
方式:DELETE
5、文档参数条件查询
a、路径方式查询
-
url:
ip:9200/test/_search?q=title:oppo
-
方式:GET
返回结果
{
"took": 409,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.8923234,
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "1001",
"_score": 1.8923234,
"_source": {
"title": "oppo",
"price": 2222
}
}
]
}
}
b、请求体携带参数方式查询
-
url:
ip:9200/test/_search
-
方式:GET
-
请求体:
{ "query":{ "match":{ "title":"oppo" } } }
精确匹配(数字)使用term
全文检索使用match
完整包含使用match_phrase
精确匹配含使用match查询字段后添加(.keyword)
c、请求体携带参数方式查询全部数据
-
url:
ip:9200/test/_search
-
方式:GET
-
请求体:
{ "query":{ "match_all":{ } } }
6、文档参数分页查询排序
-
url:
ip:9200/test/_search
-
方式:GET
-
请求体:
{
"query":{
"match_all":{
}
},
"from":0, // 偏移量
"size":2, // 查询数量
"_source":["title"], // 只查询的字段
"sort":{
"price":{ //排序字段
"order": "asc" //排序正序倒序
}
}
}
7、文档多条件查询,范围查询
-
url:
ip:9200/test/_search
-
方式:GET
-
请求体:
{
"query":{
"bool":{
"must":[ // must 相当于 and 数组中的条件必须全部满足
{
"match":{
"title":"oppo"
}
},{
"match":{
"price":2222
}
}
],
"should":[ // should相当于 or
{
"match":{
"title":"小米"
}
}
],
"filter":{ // 范围查询
"range":{
"price":{
"gt":1000
}
}
}
}
}
}
8、文档模糊查询
a、分词模糊查询
-
url:
ip:9200/test/_search
-
方式:GET
-
请求体:
{
"query":{
"match":{
"title":"小米"
}
}
}
返回结果
{
"took": 341,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 4,
"relation": "eq"
},
"max_score": 2.7208898,
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "16",
"_score": 2.7208898,
"_source": {
"title": "小米",
"price": 666
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "17",
"_score": 2.7208898,
"_source": {
"title": "小米",
"price": 777
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "15",
"_score": 1.8103764,
"_source": {
"title": "op小米po",
"price": 55
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "18",
"_score": 1.254745,
"_source": {
"title": "小红",
"price": 777
}
}
]
}
}
b、全匹配模糊查询
-
url:
ip:9200/test/_search
-
方式:GET
-
请求体:
{
"query":{
"match_phrase":{
"title":"小米"
}
}
}
返回结果
{
"took": 48,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 2.72089,
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "16",
"_score": 2.72089,
"_source": {
"title": "小米",
"price": 666
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "17",
"_score": 2.72089,
"_source": {
"title": "小米",
"price": 777
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "15",
"_score": 1.8103766,
"_source": {
"title": "op小米po",
"price": 55
}
}
]
}
}
小红就没了
c、高亮显示
-
url:
ip:9200/test/_search
-
方式:GET
-
请求体:
{
"query":{
"match_phrase":{
"title":"小米"
}
},
"highlight":{
"fields":{
"title":{}
}
}
}
返回结果
{
"took": 155,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": 2.72089,
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "16",
"_score": 2.72089,
"_source": {
"title": "小米",
"price": 666
},
"highlight": {
"title": [
"<em>小</em><em>米</em>"
]
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "17",
"_score": 2.72089,
"_source": {
"title": "小米",
"price": 777
},
"highlight": {
"title": [
"<em>小</em><em>米</em>"
]
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "15",
"_score": 1.8103766,
"_source": {
"title": "op小米po",
"price": 55
},
"highlight": {
"title": [
"op<em>小</em><em>米</em>po"
]
}
}
]
}
}
9、文档聚合查询
a、分组
-
url:
ip:9200/test/_search
-
方式:GET
-
请求体:
{
"aggs":{ //聚合操作
"price_group":{ // 分钟名称
"terms":{ // 分组
"field": "price" // 分组字段
}
}
}
}
返回结果
{
"took": 111,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 20,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "test",
"_type": "_doc",
"_id": "1",
"_score": 1.0,
"_source": {
"title": "vivo",
"price": 999
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "1002",
"_score": 1.0,
"_source": {
"title": "华为",
"price": 1999
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "1001",
"_score": 1.0,
"_source": {
"title": "oppo",
"price": 2222
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "2",
"_score": 1.0,
"_source": {
"title": "vivo2",
"price": 999
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "3",
"_score": 1.0,
"_source": {
"title": "vivo3",
"price": 999
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "4",
"_score": 1.0,
"_source": {
"title": "vivo4",
"price": 999
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "5",
"_score": 1.0,
"_source": {
"title": "vivo5",
"price": 999
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "6",
"_score": 1.0,
"_source": {
"title": "apple",
"price": 999
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "7",
"_score": 1.0,
"_source": {
"title": "aifeng",
"price": 999
}
},
{
"_index": "test",
"_type": "_doc",
"_id": "8",
"_score": 1.0,
"_source": {
"title": "lisis",
"price": 999
}
}
]
},
"aggregations": {
"price_group": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": 999,
"doc_count": 8
},
{
"key": 777,
"doc_count": 3
},
{
"key": 55,
"doc_count": 2
},
{
"key": 11,
"doc_count": 1
},
{
"key": 454,
"doc_count": 1
},
{
"key": 666,
"doc_count": 1
},
{
"key": 1999,
"doc_count": 1
},
{
"key": 2222,
"doc_count": 1
},
{
"key": 3333,
"doc_count": 1
},
{
"key": 4541,
"doc_count": 1
}
]
}
}
}
b、平均值
-
url:
ip:9200/test/_search
-
方式:GET
-
请求体:
{
"aggs":{ //聚合操作
"price_avg":{ // 分钟名称
"avg":{ // 分组
"field": "price" // 分组字段
}
}
}
}
结果
{
"aggs":{
"price_group":{
"avg":{
"field": "price"
}
}
},
"size":0
}
映射关系
映射关系不能删除只能创建新的索引,数据迁移到新的映射
1、创建索引
-
url:
ip:9200/user
-
方式:PUT
2、创建映射关系
-
url:
ip:9200/user/_mapping
-
方式:PUT
-
请求体:
{
"properties":{
"name":{ // 字段
"type":"text", // 分词模糊查询
"index":"true" // 可索引查询
},
"sex":{
"type":"keyword",
"index":"true"
},
"tel":{
"type":"keyword",// 全匹配模糊查询查询7
"index":"false"// 不可索引查询
}
}
}
可get查看映射
3、创建文档
4、查询文档
name可分词查,sex全匹配查,tel不可查
javaApi 整合springBoot
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>2.3.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.8.0</version>
</dependency>
配置yml
spring:
elasticsearch:
rest:
uris: ip:9200
username: elasticsearch
password: xxx
创建文档类
@Document
指定索引信息
@Field(type = FieldType.Text)
设置分词模糊查询
@Document(indexName = "exam-question-index")
public class ExamQuestionDocument {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@Id
private Long id;
/**
* 试题内容以及选项
*/
@Field(type = FieldType.Text)
private String qstContentAndOpts;
public ExamQuestionDocument() {
}
public ExamQuestionDocument(Long id, String qstContentAndOpts) {
this.id = id;
this.qstContentAndOpts = qstContentAndOpts;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getQstContentAndOpts() {
return qstContentAndOpts;
}
public void setQstContentAndOpts(String qstContentAndOpts) {
this.qstContentAndOpts = qstContentAndOpts;
}
@Override
public String toString() {
return "ExamQuestionDocument{" +
"id=" + id +
", qstContentAndOpts='" + qstContentAndOpts + '\'' +
'}';
}
}
工具类
@Component
public class ElasticSearchUtil {
@Resource
private ElasticsearchRestTemplate elasticsearchRestTemplate;
/**
* 创建索引
* @param clazz 包含Document注解并指定索引名称
* @return 是否创建成功
*/
public Boolean createIndex(Class<?> clazz){
// 索引名称只能是lowerCase
IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(clazz);
//创建索引
if (indexOperations.create()){
//生成映射
Document mapping = indexOperations.createMapping();
//推送映射
return indexOperations.putMapping(mapping);
}
return false;
}
/**
* 获取索引信息
* @param clazz 包含Document注解并指定索引名称
* @return 索引信息
*/
public IndexOperations getIndex(Class<?> clazz){
return elasticsearchRestTemplate.indexOps(clazz);
}
/**
* 删除索引
* @param clazz 包含Document注解并指定索引名称
* @return 是否删除成功
*/
public Boolean deleteIndex(Class<?> clazz){
IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(clazz);
return indexOperations.delete();
}
/**
* 创建文档
* @param data 文档数据
* @param docId 文档id (id存在则会覆盖)
* @param IndexName 索引名称
* @return 是否创建成功
*/
public String createDocument(Object data,String docId,String IndexName){
IndexQuery indexQuery = new IndexQuery();
// 设置文档内容
indexQuery.setObject(data);
// 设置文档id
indexQuery.setId(docId);
// 添加文档到指定索引
return elasticsearchRestTemplate.doIndex(indexQuery, IndexCoordinates.of(IndexName));
}
/**
* 批量创建文档
* @param indexQueryList 文档数据
* @param IndexName 索引名称
*/
public void createDocument(List<IndexQuery> indexQueryList,String IndexName){
// 添加文档到指定索引
elasticsearchRestTemplate.bulkIndex(indexQueryList, IndexCoordinates.of(IndexName));
}
/**
* 根据文档id获取文档
* @param id 文档id
* @param indexName 索引名称
* @param tClass 文档类class
* @param <T> 文档类型
* @return 文档
*/
public <T> T getDocumentById(String id,String indexName,Class<T> tClass){
IdsQueryBuilder idsQueryBuilder = QueryBuilders.idsQuery();
idsQueryBuilder.addIds(id);
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(idsQueryBuilder)
.build();
SearchHit<T> itemSearchHit = elasticsearchRestTemplate
.searchOne(query, tClass, IndexCoordinates.of(indexName));
assert itemSearchHit != null;
return itemSearchHit.getContent();
}
/**
* 根据文档id获取指定字段文档
* @param id 文档id
* @param indexName 索引名称
* @param tClass 文档类class
* @param fields 文档指定获取字段
* @param <T> 文档类型
* @return 文档
*/
public <T> T getDocumentById(String id,String indexName,Class<T> tClass,String... fields){
IdsQueryBuilder idsQueryBuilder = QueryBuilders.idsQuery();
idsQueryBuilder.addIds(id);
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(idsQueryBuilder)
.withFields(fields)
.build();
SearchHit<T> itemSearchHit = elasticsearchRestTemplate
.searchOne(query, tClass, IndexCoordinates.of(indexName));
assert itemSearchHit != null;
return itemSearchHit.getContent();
}
/**
* 删除文档
* @param id 文档id
* @param clazz 包含Document注解并指定索引名称
* @return 是否删除成功
*/
public String deleteDocument(String id,Class<?> clazz){
return elasticsearchRestTemplate.delete(id, clazz);
}
/**
* 分词查询指定字段文档
* @param queryColumn 请求字段
* @param queryData 模糊查询数据
* @param indexName 索引名称
* @param tClass 文档类class
* @param <T> 文档类型
* @return 模糊查询返回值
*/
public <T> SearchHits<T> queryLikeDocumentByField(String queryColumn,String queryData,String indexName,Class<T> tClass){
BoolQueryBuilder queryBuilder = new BoolQueryBuilder();
// 多条件查询
// 分词查询 查询字段需要添加@Field(type = FieldType.Text)注解
queryBuilder
.must(QueryBuilders.matchQuery(queryColumn, queryData))
// 过滤
// .filter()
;
// 高亮处理, 其实就是拼接<span/>标签, 浏览器会自动解析该标签
HighlightBuilder.Field highlightField = new HighlightBuilder.Field(queryColumn)
// 设置为red
.preTags("<span style=\"color:red\">")
.postTags("</span>");
Query query = new NativeSearchQueryBuilder()
.withQuery(queryBuilder)
// post_filter, 查询后过滤结果
// .withFilter(queryBuilder)
// 分页
//.withPageable(PageRequest.of(0, 10))
// 返回字段
//.withFields("id","qstContent")
// 排序
// .withSort()
// 聚合
// .addAggregation()
// 高亮
.withHighlightFields(highlightField)
.build();
return elasticsearchRestTemplate.search(query, tClass, IndexCoordinates.of(indexName));
}
}