下载安装(Windows版)
倒排索引
一个未经处理的数据库中,一般是以文档ID作为索引,以文档作为记录。
而倒排索引指的是将记录作为索引,将文档ID作为记录,这样可以很方便地通过记录找到其所在的位置
创建倒排索引的过程
- 首先把所有的原始数据进行编号,形成文档列表
- 把文档数据进行分词,得到很多的词条,以词条为索引。保存包含这些词条的文档的编号信息。
搜索的过程
- 当用户输入任意的词条时,首先对用户输入的数据进行分词
- 得到用户要搜索的所有词条,然后拿着这些词条去倒排索引列表中进行匹配
- 找到这些词条就能找到包含这些词条的所有文档的编号。
- 然后根据这些编号去文档列表中找到文档
安装ES
-
先配置jdk环境](https://blog.csdn.net/nuoyanli/article/details/86513950)
-
官网下载地址](https://www.elastic.co/downloads/elasticsearch),百度网盘
-
目录结构
bin 启动文件 config 配置文件 log4j2.properties 日志配置文件 jvm.options java 虚拟机相关的配置 elasticsearch.yml es的配置文件 默认9200,跨域 lib 相关jar包 modules 功能模块 plugins 插件
-
进入elasticsearch的bin目录,双击elasticsearch.bat启动服务,默认端口是9200,如下图:
-
启动完成之后,在浏览器中访问http://localhost:9200/,出现如下方所示内容表明Elasticsearch启动成功。
{
"name" : "DESKTOP-SGJPKRA", //默认集群配置
"cluster_name" : "elasticsearch", //集群名称
"cluster_uuid" : "KL5xPh2wSz6M7j7abTppUw", //自动生成的uuid
"version" : {
"number" : "7.6.0",
"build_flavor" : "default",
"build_type" : "zip",
"build_hash" : "7f634e9f44834fbc12724506cc1da681b0c3b1e3",
"build_date" : "2020-02-06T00:09:00.449973Z",
"build_snapshot" : false,
"lucene_version" : "8.4.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search" //你知道的,为了搜索
}
安装可视化界面 es head
-
下载地址 https://github.com/mobz/elasticsearch-head
-
安装部署在下载页面下有
-
解决跨域,注意空格,否则闪退(elasticsearch.yml)
http.cors.enabled: true http.cors.allow-origin: "*"
-
启动
-
cd elasticsearch-head
-
npm install
-
npm run start
-
open
http://localhost:9100/
-
- 索引 可以 看成数据库
- 查看创建的索引
安装Kabana
- 下载地址(注意版本和ES必须一致) https://www.elastic.co/cn/downloads/kibana
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kafoEHiN-1635130290236)(C:\Users\wy\AppData\Roaming\Typora\typora-user-images\image-20200625191851261.png)]
-
启动:http://localhost:5601
- bin/kibana.bat
-
汉化
-
config/kibana.yml
i18n.locale: "zh-CN"
-
IK分词器插件
分词:把一段中文划分成一个个关键字,在搜索的时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词,这显然是不符合要求的,所以我们需要安装中文分词器来解决这个问题.
- ik分词器提供了两个分词算法:
- ik_smark
- 最少切分
- ik_max_word
- 最细粒度划分
- ik_smark
- 下载地址(注意版本和ES必须一致) https://github.com/medcl/elasticsearch-analysis-ik/releases
- 将下载好的文件解压到ES目中的plugins文件夹下
- 重启ES服务,注意观察启动日志
[2020-06-25T19:39:18,660][INFO ][o.e.p.PluginsService ] [DESKTOP-SGJPKRA] loaded plugin [analysis-ik]
- 可以通过 elasticsearch-plugin list 命令查看加载的插件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xlaAG1Nb-1635130290240)(C:\Users\wy\AppData\Roaming\Typora\typora-user-images\image-20200625194401487.png)]
ik_smark
最少切分,将能认出来的词语按顺序找出来
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" : 4,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "一个",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "猪",
"start_offset" : 6,
"end_offset" : 7,
"type" : "CN_CHAR",
"position" : 3
}
]
}
ik_max_word
最细粒度划分,将能拆分出来的都尽量给拆分出来
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" : 4,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "不是",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "一个",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "一",
"start_offset" : 4,
"end_offset" : 5,
"type" : "TYPE_CNUM",
"position" : 4
},
{
"token" : "个",
"start_offset" : 5,
"end_offset" : 6,
"type" : "COUNT",
"position" : 5
},
{
"token" : "猪",
"start_offset" : 6,
"end_offset" : 7,
"type" : "CN_CHAR",
"position" : 6
}
]
}
在分词器中添加自己的词库
-
plugins\ik\config
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典 --> <entry key="ext_dict"> self.dic </entry> </properties>
// self.dic 我儿豁 不日别
Rest
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KPfzD3xD-1635130290242)(D:\youdaoyun\qq7F7B9277857495A63476C2FAA2BB9424\image-20200625201512130.png)]
关于索引的基本操作
创建索引
创建索引+类型+初始化数据
// 格式 类型不建议使用了,使用_doc默认
[谓词]/[索引]/[类型]/[id]
{
请求体
}
// 例子
PUT /db1/_doc/1
{
"name":"张三",
"age":12
}
// 对比sql,只是没有指定字段类型
Create Database db1;
Create Table type1
{
name,
age,
设置一个默认id自增
};
insert into db1 values('张三',12)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LbsOLQIy-1635130290243)(D:\youdaoyun\qq7F7B9277857495A63476C2FAA2BB9424\image-20200625214923532.png)]
创建索引不增加数据,添加字段类型约束
如果不添加约束,也会自动给你添加的
PUT /索引
{
"mappings": {
"properties": {
"字段1":{
"type": "text"
},
"字段2":{
"type": "integer"
},
"字段3":{
"type":"date"
}
}
}
}
// 例子
PUT /db2
{
"mappings": {
"properties": {
"name":{
"type": "text"
},
"age":{
"type": "integer"
},
"birthday":{
"type":"date"
}
}
}
}
// 对比sql
Create Database db2;
Create Table _doc
{
name text,
age int,
birthday date
设置一个默认id自增
};
修改
整体更新
还是使用上面的即可
局部更新
// 结尾加上/_update关键字
// 将要修改的字段放入"doc"对象中
POST /db3/_doc/2/_update
{
"doc":{
"age":12
}
}
删除
删除索引
DELETE /索引
删除指定id的数据
DELETE /索引/类型/id
DELETE /db3/_doc/1
获取
获取索引信息
GET 索引
关于文档的基本操作
简单查询
match 分词查询
//简写
GET /db1/_doc/_search?q=name:"张三"
//相当于
GET /db1/_doc/_search
{
"query":{
"match":{
"name":"张三"
}
}
}
// C#
var searchResults = ElasticSearchHelp._client.Search<Student>(s => s
.Query(q => q
.Match(m => m
.Field("name")
.Query("张三")
))
);
精准查询
// 如果没有分词则使用 字段名,如果分词了就使用字段名.keyword
GET /db1/_doc/_search
{
"query":{
"term":{
"name.keyword":"张三萨拉赫"
}
}
}
// C#
var searchResults = ElasticSearchHelp._client.Search<Student>(s => s
.Query(q => q
.Term(m => m
.Field("name.keyword")
.Value("赵")
))
);
排序
GET /db1/_doc/_search
{
"sort":{
"age":"asc"
}
}
// C#
var searchResults = ElasticSearchHelp._client.Search<Student>(s => s
.Sort(so=>so.Ascending(so=>so.Age))
);
limit
从0开始显示2条数据
GET /db1/_doc/_search
{
"from":0,
"size":2
}
// C#
var searchResults = ElasticSearchHelp._client.Search<Student>(s => s
.From(0)
.Size(3)
);
Bool
- must 相当于and
GET /db1/_doc/_search
{
"query":{
"bool":{
"must":[{
"match":{
"name":"张三"
}
},{
"match":{
"age":3
}
}]
}
}
}
// C#
var searchResults = ElasticSearchHelp._client.Search<Student>(s => s
.Query(q=>
q.Bool(b=>
b.Must(m=>
m.Match(
m=>m.Field(f=>f.Name).Query("赵")),
m=>m.Term(m=>m.Field(f=>f.Age).Value(17))
)))
);
- should 相当于or
GET /db1/_doc/_search
{
"query":{
"bool":{
"should":[{
"match":{
"name":"张三"
}
},{
"match":{
"age":3
}
}]
}
}
}
- must_not 相当于not
filter
- 范围操作符
- gt :: 大于
- gte:: 大于等于
- lt :: 小于
- lte:: 小于等于
// 查询年龄在20-100岁的数据
GET /db1/_doc/_search
{
"query":{
"range":{
"age":{
"gte":20,
"lt":100
}
}
}
}
// C#
var searchResults = ElasticSearchHelp._client.Search<Student>(s => s
.Query(q=>
q.Range(r=>
r.Field(f=>f.Age)
.GreaterThan(0)
.LessThan(20)
))
);
聚合查询
- avg 平均值
- cardinality 去重
- stats 返回多种结果(count,min,max,avg,sum)
- Percentiles 百分位数(我也不知道是个什么)
// 相当于 avg(age) as avg_age
GET /db1/_doc/_search
{
"size": 0,
"aggs" : {
"avg_age" : {
"avg" : {
"field" : "age"
}
}
}
}
// C#
var searchResults = ElasticSearchHelp._client.Search<Student>(s => s
.Size(0)
.Aggregations(a=>a
.Average("Average", a=>a.Field(f=>f.Age))
.Max("Max", a => a.Field(f => f.Age))
.Stats("Stats", a => a.Field(f => f.Age))
)
);
.NET CORE 中使用
- api文档 https://www.elastic.co/guide/en/elasticsearch/client/net-api/7.x/index.html
- 安装nuget 【Nest】 注意版本对应es的版本