优点:容错性好;单点故障时,可以通过复制数据到不同的服务器上达到容错的目的;
使用前提:没有频繁更新(一秒内有大量的更改操作),不需要事务处理,需要对数据进行检索,统计;
存储形式:ES中,存储数据的基本单位就是索引,比如说ES中存储了一些订单系统的销售数据,就因该在ES中创建一个索引(order—index),所有的销售数据就会都写到这个索引里面去,一个索引就像一个数据库,mapping就相当于表的结构定义,定义了什么字段类型等,你往index里添加一行数据就叫做一个document,每一个document有多个filed,每一个filed就代表这个document的一个字段的值。
数值类型(long、integer、short、byte、double、float)
Date 日期类型
boolean布尔类型
Text 支持全文搜索
Keyword 不支持全文搜索,例如:phone这种数据,用一个整体进行匹配就ok了,也不要进行分词处理
Geo 这里主要用于地理信息检索、多边形区域的表达。
注意:ES的自动映射是很方便的,但是实际业务中,对于关键字段类型,我们都是通常预先定义好,这样可以避免ES自动生成的字段类型不是你想要的类型。
基本语法
GET /{索引名}/_search
{
"from" : 0, // 搜索结果的开始位置
"size" : 10, // 分页大小,也就是一次返回多少数据
"_source" :[ ...需要返回的字段数组... ],
"query" : { ...query子句... },
"aggs" : { ..aggs子句.. },
"sort" : { ..sort子句.. }
}
GET /{索引名}/_search
{
"query": {
"range": {
"{FIELD}": {
"gte": 100,
"lte": 200
}
}
}
}
{FIELD} - 字段名
gte范围参数 - 等价于>=
lte范围参数 - 等价于 <=
范围参数可以只写一个,例如:仅保留 “gte”: 100, 则代表 FIELD字段 >= 100
gt - 大于 ( > )
gte - 大于且等于 ( >= )
lt - 小于 ( < )
lte - 小于且等于 ( <= )
GET /{索引名}/_search
{
"query": {
"bool": { // bool查询
"must": [], // must条件,类似SQL中的and, 代表必须匹配条件
"must_not": [], // must_not条件,跟must相反,必须不匹配条件
"should": [] // should条件,类似SQL中or, 代表匹配其中一个条件
}
}
}
GET /{索引名}/_search
{
"query": {
...查询条件....
},
"sort": [
{
"{Field1}": { // 排序字段1
"order": "desc" // 排序方向,asc或者desc, 升序和降序
}
},
{
"{Field2}": { // 排序字段2
"order": "desc" // 排序方向,asc或者desc, 升序和降序
}
}
....多个排序字段.....
]
}
拆分相当于 雷神加速器被拆分为“雷”“神” “加” “速” “器” match 搜索雷、神、加都能够搜索出结果
match查询的结果中一定会有“雷”“神” “加” “速” “器” 字样
term的查询结果就会包含只有“雷”“神” “加” “速” “器” 这个分词结果的数据
match在匹配时会对所查找的关键词进行分词,然后按分词匹配查找,而term会直接对关键词进行查找。一般模糊查找的时候,多用match,而精确查找时可以使用term。
go-client参数
elastic.SetURL(url)用来设置ES服务地址,如果是本地,就是127.0.0.1:9200。支持多个地址,用逗号分隔即可。
elastic.SetBasicAuth("user", "secret")这个是基于http base auth 验证机制的账号密码。
elastic.SetGzip(true)启动gzip压缩
elastic.SetHealthcheckInterval(10*time.Second)用来设置监控检查时间间隔
elastic.SetMaxRetries(5)设置请求失败最大重试次数,v7版本以后已被弃用
elastic.SetSniff(false)允许指定弹性是否应该定期检查集群(默认为true)
elastic.SetErrorLog(log.New(os.Stderr, "ELASTIC ", log.LstdFlags)) 设置错误日志输出
elastic.SetInfoLog(log.New(os.Stdout, "", log.LstdFlags)) 设置info日志输出
查询操作
{
"query": {
"bool": {
"must": [
{
"term": {
"Port": "443"
}
}
,
{
"term": {
"State": "established"
}
}
],
"must_not": [
{
"term": {
"RemoteAddr": "0.0.0.0"
}
}
],
"should": [ ]
}
},
"from": 0,
"size": 250,
"sort": [ ],
"aggs": { }
}
Go调用代码
//多条件精确查询
query := elastic.NewBoolQuery()
//排除特定信息用must_not
query = query.MustNot(elastic.NewTermQuery("RemoteAddr", "0.0.0.0"), elastic.NewTermQuery("RemoteAddr", "127.0.0.1"))
if ip != "" {
query = query.Must(elastic.NewTermQuery("IP", ip))
}
if value != "" {
query = query.Must(elastic.NewTermQuery("Port", value))
}
if state != "" {
//注意term需要小写才能识别 因为分词器会将大写字母转换为小写
query = query.Must(elastic.NewTermQuery("State", strings.ToLower(state)))
}
//查询需要指定size 否则默认为Es查询10条数据,可通过修改ES配置或指定size修改
res, err := Client.Search("network").Query(query).Size(size).Do(context.Background())
if err != nil {
err...
}
//判断返回结果数量进行数据处理
if res.Hits.TotalHits.Value > 0 {
for _, v := range res.Hits.Hits {
//v.Source为搜索结果
json.Unmarshal(v.Source, &temp)
}
}
//模糊查询
query := elastic.NewBoolQuery()
if ip != "" {
query = query.Must(elastic.NewTermQuery("IP", ip))
}
if value != "" {
query = query.Must(elastic.NewWildcardQuery("Name.keyword", value))
}
res, err := Client.Search("application").Query(query).Size(size).Do(context.Background())
if err != nil {
return nil, err
}
if res.Hits.TotalHits.Value > 0 {
for _, v := range res.Hits.Hits {
//v.Source为搜索结果
json.Unmarshal(v.Source, &temp)
}
}
/*下面是简单的CURD*/
//创建
func Create(str interface{}, index, id string) error {
conn := Client.Index()
_, err := conn.Index(index).Id(id).BodyJson(str).Do(context.Background())
if err != nil {
return err
}
return nil
}
//删除
func Delete(index, id string) error {
_, err := Client.Delete().Index(index).
Id(id).
Do(context.Background())
if err != nil {
return err
}
return nil
}
//修改
func Update(str interface{}, index, id string) error {
_, err := Client.Update().
Index(index).
Id(id).
Doc(str).
Do(context.Background())
if err != nil {
return err
}
return nil
}
//查找
func SelectEsToBytes(index, id string) ([]byte, error) {
//通过id查找
get1, err := Client.Get().Index(index).Id(id).Do(context.Background())
if err != nil {
return nil, err
}
if get1.Found {
return get1.Source, nil
}
return get1.Source, errors.New("filed Not Found")
}