主頁 >  其他 > 搜索引擎springboot集成(elasticSearch)

搜索引擎springboot集成(elasticSearch)

2021-02-12 10:32:11 其他

各位小伙伴們,今天是今年的最后一天,這是我今年的最后一篇博客,在這里祝大家新年快樂!本次講的是近幾年比較流行的search搜索引擎,本文寫的比較粗略,希望大家看了會有所識訓,如若寫錯,請在評論區指出,我感激不盡!

1 搜索引擎springboot集成(elasticSearch)

1.1 為什么要使用ElasticSearch

? 實際專案中,我們建立一個網站或應用程式,并要添加搜索功能,令我們受打擊的是:搜索作業是很難的,我們希望我們的搜索解決方案要快,我們希望有一個零配置和一個完全免費的搜索模式,我們希望能夠簡單地使用JSON/XML通過HTTP的索引資料,我們希望我們的搜索服務器始終可用,我們希望能夠從一臺開始并在需要擴容時方便地擴展到數百,我們要實時搜索,我們要簡單的多租戶,我們希望建立一個云的解決方案,

? 雖然全文搜索領域,Lucene可以被認為是迄今為止最先進、性能最好的、功能最全的搜索引擎庫,但是,Lucene只是一個庫,想要使用它,你必須使用Java來作為開發語言并將其直接集成到你的應用中,更糟糕的是,Lucene的配置及使用非常復雜,你需要深入了解檢索的相關知識來理解它是如何作業的,

1.2 ElasticSearch(簡稱ES)

? ES即為了解決原生Lucene使用的不足,優化Lucene的呼叫方式,并實作了高可用的分布式集群的搜索方案,其第一個版本于2010年2月出現在GitHub上并迅速成為最受歡迎的專案之一,

? 首先,ES的索引庫管理支持依然是基于Apache Lucene?的開源搜索引擎,ES也使用Java開發并使用Lucene作為其核心來實作所有索引和搜索的功能,但是它的目的是通過簡單的 RESTful API來隱藏Lucene的復雜性,從而讓全文搜索變得簡單,Lucene直接通過java API呼叫,而ES把這些API呼叫程序進行了的封裝為簡單RESTful請求,讓我們呼叫起來更加簡單.

? 不過,ES的核心不在于Lucene,其特點更多的體現為:分布式的實時檔案存盤,每個欄位都被索引并可被搜索,分布式的實時分析搜索引擎,可以擴展到上百臺服務器,處理PB級結構化或非結構化資料,高度集成化的服務,你的應用可以通過簡單的 RESTful API、各種語言的客戶端甚至命令列與之互動,上手Elasticsearch非常容易,它提供了許多合理的預設值,并對初學者隱藏了復雜的搜索引擎理論,它擁有開瓶即飲的效果(安裝即可使用),只需很少的學習既可在生產環境中使用,

? Lucene和ES聯系,區別:專案中為啥使用ES而不用Lucene.

? 聯系:ElasticSearch封裝了Lucene,讓使用變得更簡單,在高可用上面做得更好,

? 區別:ElasticSearch除了擁有Lucene所有優點以外,還擁有自己優點.

? 可用性:支持集群沒有單點故障

? 擴展性:支持集群擴展

? 一般lucene在中小型專案中使用(但是也能使用es),而ES在大型專案中使用.因為ES支持在集群環境使用,并且自身也支持集群.

2 ES安裝及使用說明

官網地址=>https://www.elastic.co/cn/elasticsearch

自行搜索

3 ES資料管理

3.1 什么是ES中的檔案

ES是面向檔案(document oriented)的,這意味著它可以存盤整個物件或檔案(document),然而它不僅僅是存盤,還會索引(index,創建索引)每個檔案的內容使之可以被搜索,在ES中,你可以對檔案(而非成行成列的資料)進行索引、搜索、排序、過濾,

ES使用Javascript物件符號(JavaScript Object Notation),也就是JSON,作為檔案序列化格式,JSON現在已經被大多語言所支持,而且已經成為NoSQL領域的標準格式,

ES存盤的一個員工檔案的格式示例:

{

“email”: “wb@bbcc.com”,

“name”: “文兵”,

“info”: {

“addr”: “四川省成都市”,

“age”: 30,

“interests”: [ “櫻桃”, “粉嫩” ]

},

“join_date”: “2014-06-01”

}

盡管原始的 employee物件很復雜,但它的結構和物件的含義已經被完整的體現在JSON中了,在ES中將物件轉化為JSON并做索引要比在表結構中做相同的事情簡單的多,

一個檔案不只有資料,它還包含元資料(metadata)—關于檔案的資訊,三個必須的元資料節點是:

節點說明
_index索引庫,檔案存盤的地方
_type檔案型別(6.x之后取消掉了這個屬性)
_id檔案的唯一標識

**_index:**索引庫,類似于關系型資料庫里的“資料庫”—它是我們存盤和索引關聯資料的地方,

**_type:**型別,類似于關系型資料庫中表.在應用中,我們使用物件表示一些“事物”,例如一個用戶、一篇博客、一個評論,或者一封郵件,可以是大寫或小寫,不能包含下劃線或逗號,我們將使用 employee 做為型別名,

_id: 與 _index 和 _type 組合時,就可以在ELasticsearch中唯一標識一個檔案,當創建一個檔案,你可以自定義 _id ,也可以讓Elasticsearch幫你自動生成,

另外還包括:_uid 檔案唯一標識(_type#_id)

**_source:**檔案原始資料

**_all:**所有欄位的連接字串

3.2 檔案的增刪改

? 我們以員工物件為例,我們首先要做的是存盤員工資料,每個檔案代表一個員工,在ES中存盤資料的行為就叫做索引(indexing),檔案歸屬于一種型別(type),而這些型別存在于索引(index)中,我們可以簡單的對比傳統資料庫和ES的對應關系:

關系資料庫(MYSQL) -> 資料庫DB-> 表TABLE-> 行ROW-> 列Column

Elasticsearch -> 索引庫Indices -> 型別Types -> 檔案Documents -> 欄位Fields

ES集群可以包含多個索引(indices)(資料庫),每一個索引庫中可以包含多個型別(types)(表),每一個型別包含多個檔案(documents)(行),然后每個檔案包含多個欄位(Fields)(列),

創建索引檔案

  1. 使用自己的ID創建

    PUT {index}/{type}/{id}
    {
      "field": "value",
      ...
    }
    
  2. 使用內置ID創建

    POST {index}/{type}
    {
      "field": "value",
      ...
    }
    
  3. 獲取指定ID的檔案

    GET itsource/employee/123
    
  4. 更新檔案

    PUT {index}/{type}/{id}
    {
      "field": "value",
      ...
    }
    

    跟創建語法一樣,但是會改變版本號

  5. 洗掉檔案

    DELETE {index}/{type}/{id}
    

    注意:盡管檔案不存在,但_version依舊增加了,這是內部記錄的一部分,它確保在多節點間不同操作可以有正確的順序

    put和post是差不多的,都可以用來修改和添加,唯一區別就是,在添加時put需要手動給id而post不需要賦id,系統自動給個隨機id

3.3 檔案的簡單查詢(searchAPI)

GET /_search
GET /woniu47/_search
GET /woniu47,woniu48/_search
GET /woniu*/_search

URLsearch

通過ID獲取

GET /woniu47/_doc/1

只回傳檔案內容,不要元資料:

GET /woniu47/_doc/1/_source

查詢字串搜索:

回傳檔案的部分欄位:

GET /woniu47/_doc/1?_source=name,age

查詢年齡為25歲的學員

GET /woniu47/_search?q=age:25

組合查詢:

組合查詢:

+表示并且,多個條件做且運算====>MUST

空格表示或,多個條件做或運算====>SHOULD

-表示非,多個條件做非運算====>MUST_NOT

+name:john +tweet:mary

+name:(mary john) +date:>2014-09-10 +(aggregations geo)

age[20 TO 30]

查詢年齡在25到28 (兩邊都包括)或則姓名為wangwu的學員

GET /woniu47/_search?q=age:>=25 +age<=28 name:wangwu
GET /woniu47/_search?q=age[25 TO 28] name:wangwu

中括號可以換成大括號,中括號有=大括號沒有

分頁:

查詢20歲以上的學員,顯示3條

GET /woniu47/_search?q=age:>=20&size=3

查詢20歲以上的學員,每頁顯示3條,顯示第2頁

GET /woniu47/_search?q=age:>=20&size=3&from=3

查詢引數說明:

NameDescription
q標識查詢字串
df在查詢中,沒有定義欄位前綴的情況下默認欄位的前綴
analyzer在分析查詢字串時,分析器的名字
default_operator被用到的默認操作,有AND和OR兩種,默認是OR
explain對于每一個命中,對怎樣得到命中得分的計算給出一個解釋
_source將其設定為false,查詢就會放棄檢索_source欄位,也可以通過設定檢索部分檔案
fields命中的檔案回傳的欄位
sort排序執行,可以fieldName、fieldName:asc
track_scores當排序的時候,將其設定為true,可以回傳相關度得分
from分頁查詢起始點,默認0
size查詢數量,默認10
search_type搜索操作執行的型別

4 索引與分詞

4.1 什么是倒排索引

? 倒排索引是先將檔案進行分詞處理,標記每個詞都出現在哪些檔案里面,這樣就可以快速查詢某個詞所出現的檔案位置,與之對應的是“正排索引”,例如我們看一本書的目錄,從前往后查找目錄,就是正排索引,

? 我們先來看3組檔案,我們將檔案編號分別列為1、2、3,

bb

這3個檔案里,核心詞是“衛生間隔斷”,如果你在搜索引擎上,直接搜索衛生間隔斷,拋開文章內容,單看標題,哪個排第一?沒錯,就是檔案1會出現在第一位,為什么?

因為倒排索引里,會通過單詞詞典,統計一個單詞在檔案里出現的位置,我們將上述檔案里出現的詞,都賦予一個ID,

? 這是一個最簡單的倒排索引示意圖:

cc

4.2 什么是分詞

分詞是指將文本轉換成一系列單詞的程序,也可以叫文本分析,在es里面稱為Analysis,如下圖所示:

a

分詞器是ES中專門處理分詞的組件,英文為Analyzer,它的組成如下:

  • Character Filters

    針對原始文本進行處理,比如去除html特殊標記

  • Tokenizer

    將原始文本按照一定規則切分為單詞

  • Token Filters

    針對tokenizer處理的單詞進行再加工,比如轉小寫、洗掉或新增等處理

4.3 Analyze API

ES提供了一個測驗分詞的api介面,方便驗證分詞效果,endpoint是_analyze

  1. 直接指定analyzer進行測驗

    POST _analyze
    {
      "analyzer": "standard",
      "text": "hello world"
    }
    
  2. 直接指定索引中的欄位進行測驗

    POST woniu47/_analyze
    {
      "field": "name",
      "text": "hello java"
    }
    

ES自帶分詞器如下:

NameDescription
standard默認分詞器,按詞切分,支持多語言,小寫處理
simple按照非字母切分,小寫處理
whitespace按照空格切分
stop相比simple 多了stop word處理(語氣2組詞等修飾性的詞語,比如the、an、的、這等等)
keyword不分詞,直接將輸入作為一個單詞輸出
pattern通過正則運算式自定義分割符,默認是\W+, 即非字詞的符號作為分隔符

4.4 中文分詞器

中文分詞器是將一個漢字序列切分成一個一個單獨的詞,在英語中,單詞之間是以空格作為自然分界符,漢語中詞沒有一個形式上的分界符,背景關系不同,分詞結果迥異,比如交叉歧義問題,比如下面兩種分詞都合理:

  • 乒乓球拍/賣/完了
  • 乒乓球/拍賣/完了

常用分詞系統

  1. IK

    • 實作中英文單詞的切分,支持ik_smart、ik_maxword等模式,

    • 可自定義詞庫,支持熱更新分詞詞典

    • https://github.com/medcl/elasticsearch-analysis-ik

  2. jieba

    • python中最流行的分詞系統,支持分詞和詞性標注
    • 支持繁體分詞、自定義詞典、并行分詞等
    • https://github.com/sing1ee/elasticsearch-jieba-plugin

IK的使用

  1. 安裝

    • git clone https://github.com/medcl/elasticsearch-analysis-ik
    • cd elasticsearch-analysis-ik
    • mvn clean
    • mvn compile
    • mvn package
    • 拷貝和解壓release下的檔案: #{project_path}/elasticsearch-analysis-ik/target/releases/elasticsearch-analysis-ik-*.zip 到你的 elasticsearch 插件目錄, 如: plugins/ik 重啟elasticsearch
  2. 測驗

    POST _analyze
    {
      "analyzer": "ik_smart",
      "text": "中華人民共和國國歌"
    }
    
    POST _analyze
    {
      "analyzer": "ik_max_word",
      "text": "中華人民共和國國歌"
    }
    
  3. ik_smart與ik_max_word的區別

    ik_max_word: 會將文本做最細粒度的拆分,比如會將“中華人民共和國國歌”拆分為“中華人民共和國,中華人民,中華,華人,人民共和國,人民,人,民,共和國,共和,和,國國,國歌”,會窮盡各種可能的組合,適合 Term Query;

    ik_smart: 會做最粗粒度的拆分,比如會將“中華人民共和國國歌”拆分為“中華人民共和國,國歌”,適合 Phrase 查詢

注意: 在config檔案夾下面有很多擴展詞的配置

5 Mapping(檔案映射)

ES的檔案映射(mapping)機制用于進行欄位型別確認(欄位是什么型別,什么分詞器),將每個欄位匹配為一種確定的資料型別,類似于資料庫的表結構定義,主要作用如下:

  1. 定義Index下的欄位名(Field Name)
  2. 定義欄位的型別,比如數值型、字串型、布爾型等
  3. 定義倒排索引相關配置,比如是否索引、記錄position等

查看某個Index的Mapping

GET woniu47/_mapping

5.1 自定義Mapping

創建一個Index的映射

PUT woniu48
{
  "mappings": {
    "properties": {
      "name": {
        "type": "keyword"
      },
      "age": {
        "type": "integer"
      },
      "desc": {
        "type": "text",
        "analyzer": "ik_smart"
      }
    }
  }
}

Mapping中的欄位型別一旦設定后,禁止直接修改,因為Lucene實作的倒排索引生成后不允許修改

通過dynamic引數來控制欄位的新增

  • true(默認)允許自動新增欄位
  • false 不允許自動新增欄位,但是檔案可以正常寫入,但無法對欄位進行查詢等操作
  • strict 檔案不能寫入,報錯
PUT woniu48
{
  "mappings": {
    "dynamic": "false",
    "properties": {
      "name": {
        "type": "keyword"
      },
      "age": {
        "type": "integer"
      },
      "desc": {
        "type": "text",
        "analyzer": "ik_smart"
      }
    }
  }
}

copy_to

  • 將該欄位的值復制到目標欄位,實作類似_all的作用
  • 不會出現在_source中,只用來搜索
PUT woniu48
{
  "mappings": {
    "dynamic": "false",
    "properties": {
      "name": {
        "type": "keyword",
        "copy_to": "full_name"
      },
      "age": {
        "type": "integer"
      },
      "desc": {
        "type": "text",
        "analyzer": "ik_smart",
        "copy_to": "full_name"
      },
      "full_name": {
        "type": "text"
      }
    }
  }
}

index

  • 控制當前欄位是否索引,默認為true,即記錄索引,false不記錄,即不可搜索
PUT woniu48
{
  "mappings": {
    "dynamic": "false",
    "properties": {
      "name": {
        "type": "keyword",
        "index": false
      },
      "age": {
        "type": "integer"
      },
      "desc": {
        "type": "text",
        "analyzer": "ik_smart",
        "copy_to": "full_name"
      }
    }
  }
}

name欄位不能夠用來搜索

null_value

  • 當欄位遇到null值時的處理策略,默認為null,即空值,此時ES會忽略該值,不會創建索引,可以通過設定該值得一個空值的替換值來對空值進行索引,可以用替換值進行對空值的搜索
PUT woniu48
{
  "mappings": {
    "properties": {
      "name": {
        "type": "keyword"
      },
      "age": {
        "type": "integer"
      },
      "desc": {
        "type": "text",
        "analyzer": "ik_smart"
      },
      "sex": {
        "type": "keyword",
        "null_value": "null"
      }
    }
  }
}

使用null替換了空值,下面添加一個空值

PUT woniu48/_doc/1
{
  "name": "zs",
  "age": 23,
  "desc": "中國人很好",
  "sex": null
}

可以使用替換的null值來進行空值搜索

GET woniu48/_search
{
  "query": {
    "match": {
      "sex": "null"
    }
  }
}

ignore_above

  • 該屬性是keyword型別的一個屬性,用來規定欄位值長度,超出這個長度的欄位將不會被索引,但是會存盤,
PUT woniu48
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "fields": {
          "pinyin": {
            "type": "keyword",
            "ignore_above": 5 
          }
        }
      },
      "age": {
        "type": "integer"
      }
    }
  }
}

多欄位特性 multi-fields

  • 允許對同一個欄位采用不同的配置,比如分詞,常見的例子如一個欄位我需要通過索引分詞查詢也需要能夠通過精裝匹配查詢
PUT woniu48
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "fields": {
          "pinyin": {
            "type": "keyword"
          }
        }
      },
      "age": {
        "type": "integer"
      }
    }
  }
}

index_options

用來控制倒排索引記錄的內容

  • docs: 只記錄doc id
  • freqs : 記錄doc id和term frequencies
  • positions: 記錄doc id、term frequencies和term position
  • offsets: 記錄doc id、term frequencies、term position和character offsets

text型別默認配置為positions,其他默認為docs,記錄內容越多,占用空間越大

5.2 資料型別

  1. 核心資料型別
    • 字串型: text、keyword
    • 數值型: long、integer、short、byte、double、float、half_float、scaled_float
    • 日期型別: date
    • 布爾型別: boolean
    • 二進制型別: binary
    • 范圍型別: integer_range、float_range、long_range、double_range、date_range
  2. 復雜資料型別
    • 陣列型別: array
    • 物件型別: object
    • 嵌套型別: nested object
  3. 地理位置資料型別
    • geo_point
    • geo_shape
  4. 專用型別
    • ip: 記錄IP地址
    • completion: 實作自動補全
    • token_count: 記錄分詞數
    • murmur3: 記錄字串hash值

5.3 Dynamic Mapping(自動映射)

ES在沒有配置Mapping的情況下新增檔案,ES可以自動識別檔案欄位型別,并動態生成欄位和型別的映射關系,

ES是依靠JSON檔案的欄位型別來實作自動識別欄位型別,支持的型別如下:

JSON型別ES型別
null忽略
booleanboolean
浮點型別float
整數long
objectobject
array由第一個非null值得型別決定
string匹配為日期格式則設為date型別(默認開啟);
匹配為數字的話設為float或long型別(默認關閉)設為text型別,并附帶keyword子欄位

6 DSL查詢

由ES提供豐富且靈活的查詢語言叫做DSL查詢(Query DSL),將查詢陳述句通過http request body發送到ES,主要包含如下引數:

  • query符合Query DSL語法的查詢陳述句
  • from、size
  • timeout
  • sort
  • ,,,

例如:

GET woniu48/_search
{
  "query": {
    "term": {
      "name": "lisi"
    }
  }
}

基于JSON定義的查詢語言,主要包含如下兩種型別

  1. 欄位類查詢

    如term、match、range等,只針對某一個欄位進行查詢

  2. 復合查詢

    如bool查詢等,包含一個或多個欄位類查詢或則復合查詢陳述句

6.1 欄位類查詢

欄位類查詢主要包括以下兩類:

  1. 全文匹配
    • 針對text型別的欄位進行全文檢索,會對查詢陳述句先進行分詞處理,如match、match_phrase等query型別
  2. 單詞匹配
    • 不會對查詢陳述句做分詞處理,直接匹配欄位的倒排索引,如term、terms、range等query型別

全文匹配(Match Query)

GET woniu48/_search
{
  "query": {
    "match": {
      "username": "alfred way"
    }
  }
}

Match Query流程

a

通過operator引數可以控制單詞間的匹配關系,可選項為or或則and

GET woniu48/_search
{
  "query": {
    "match": {
      "desc": {
        "query": "非常漂亮",
        "operator": "and"
      }
    }
  }
}

上面查詢如果分詞器分詞為“非常”、“漂亮”兩個詞,查詢匹配結果就必須同時包含這兩個詞的檔案

單詞匹配(Term Query)

GET woniu48/_search
{
  "query": {
    "term": {
      "name": "lisi"
    }
  }
}

一次傳入多個單詞進行查詢

GET woniu48/_search
{
  "query": {
    "terms": {
      "name": [
        "lisi",
        "wangmazi"
      ]
    }
  }
}

Range Query(范圍查詢)

GET woniu48/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 20,
        "lte": 23
      }
    }
  }
}

6.2 復合查詢

復合查詢是指包含欄位類查詢或復合查詢的型別,主要包括以下幾類:

  1. constant_score query
  2. bool query *
  3. dis_max query
  4. function_score query
  5. boosting query

Bool Query

布爾查詢由一個或多個布爾子句組成,主要包含如下4個:

NameDescription
filter只過濾符合條件的檔案,不計算相關性得分
must檔案必須復合must中的所有條件,會影響相關性得分
must_not檔案必須不符合must_not中的所有條件
should檔案可以符合should中的條件,會影響相關性得分
  1. Filter

    Filter查詢只過濾符合條件的檔案,不會進行相關性算分

    • ES針對Filter會有智能快取,因此其執行效率很高
    • 做簡單匹配查詢且不考慮算分時,推薦使用filter替代query等
    GET woniu48/_search
    {
      "query": {
        "bool": {
          "filter": [
            {
              "term": {
                "name": "admin"
              }
            },
            {
              "range": {
                "age": {
                  "gte": 25
                }
              }
            }
          ]
        }
      }
    }
    
  2. must

    GET woniu48/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "desc": "漂亮的人"
              }
            },
            {
              "range": {
                "age": {
                  "gte": 22
                }
              }
            }
          ]
        }
      }
    }
    
  3. must_not

    查詢描述里面經過分詞有“漂亮”一詞以及不帶“非常”一詞的結果

    GET woniu48/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "desc": "漂亮的人"
              }
            }
          ],
          "must_not": [
            {
              "match": {
                "desc": "非常好"
              }
            }
          ]
        }
      }
    }
    
  4. should

    • 只包含should時,檔案必須至少滿足一個條件(minimun_should_match可以控制滿足條件的個數或則百分比)

      例如:下面至少滿足一個條件

      GET woniu48/_search
      {
        "query": {
          "bool": {
            "should": [
              {
                "match": {
                  "desc": "漂亮的人"
                }
              },
              {
                "range": {
                  "age": {
                    "lte": 20
                  }
                }
              }
            ]
          }
        }
      }
      

      例如:下面需要滿足兩個條件

      GET woniu48/_search
      {
        "query": {
          "bool": {
            "should": [
              {
                "match": {
                  "desc": "漂亮的人"
                }
              },
              {
                "range": {
                  "age": {
                    "lte": 20
                  }
                }
              }
            ],
            "minimum_should_match": 2
          }
        }
      }
      
    • 同時包含should和must時,檔案不必滿足should中的條件,但是如果滿足條件,會增加相關性得分

      該查詢只會以must匹配來搜索

      GET woniu48/_search
      {
        "query": {
          "bool": {
            "should": [
              {
                "range": {
                  "age": {
                    "lte": 19
                  }
                }
              }
            ],
            "must": [
              {
                "match": {
                  "desc": "漂亮的人"
                }
              }
            ]
          }
        }
      }
      
  5. 綜合實體

    查詢年齡大于20并且包含“漂亮的人”描述或則年齡小于18的學員,分頁顯示第2頁,每頁顯示2條,且按照年齡由低到高排序

    GET woniu48/_search
    {
      "query": {
        "bool": {
          "should": [
            {
              "bool": {
                "must": [
                  {
                    "match": {
                      "desc": "漂亮的人"
                    }
                  },
                  {
                    "range": {
                      "age": {
                        "gte": 20
                      }
                    }
                  }
                ]
              }
            },
            {
              "range": {
                "age": {
                  "lte": 18
                }
              }
            }
          ]
        }
      },
      "from": 2,
      "size": 2,
      "sort": [
        {
          "age": {
            "order": "desc"
          }
        }
      ]
    }
    

7 SpringBoot集成

可以通過Spring Data Elasticsearch來進行操作,boot對其進行了集成:

  1. 導包

    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>
    
  2. 配置連接

    spring:
      elasticsearch:
        rest:
          uris:
          - http://localhost:9200
    
  3. 注入模板物件

    @Autowired
    ElasticsearchOperations operations;
    

7.1 物件映射

ES的檔案對應于Java的物件,可以通過Spring-Data-Es提供的注解來進行關聯:

@Data
@Document(indexName = "woniu48")
public class Student {
	
	@Id
	@Field(type = FieldType.Integer,name = "id")
	private Integer id;
	
	@Field(type = FieldType.Keyword,name="name")
	private String name;
	
	@Field(type = FieldType.Integer,name="age")
	private Integer age;
	
	@Field(type = FieldType.Text,analyzer = "ik_max_word",name = "desc")
	private String desc;

}
  • @Document: 在類級別應用,以指示該類是映射到ES的哪一個Index,最重要的屬性是:
    • indexName: 用于存盤此物體的索引的名稱
  • @Id: 用來標識ID
  • @Field: 在欄位級別應用并定義欄位的屬性:
    • name: 欄位名稱
    • type: 欄位型別
    • analyzer: 分詞器

7.2 操作

保存(新增與更新)物件:

Student stu = new Student();
stu.setId(3333);
stu.setName("張三豐");
stu.setDesc("此人漲得不好看");
stu.setAge(100);
operations.save(stu);

洗掉物件:

//第一個引數是id
operations.delete("3333", Student.class);

查詢物件:

查詢有三種主要方式:

  1. 通過CriteriaQuery條件來查詢,可以簡單組合條件,不能分詞,適用于非常簡單的查詢

    //查詢年齡在20-25之間或則名稱是"admin"的學員
    Criteria c = new Criteria("age").between(20, 25)
    	.or("name").is("admin");			
    CriteriaQuery cq = new CriteriaQuery(c);
    SearchHits<Student> shs = operations.search(cq, Student.class);
    System.out.println(shs.getTotalHits());
    shs.getSearchHits().forEach(student -> {
    	System.out.println(student.getContent().getName()+":"+student.getContent().getAge());
    });
    
  2. 通過StringQuery來查詢,直接在java這邊構建查詢json字串,不推薦使用

  3. 通過NativeSearchQuery來構建復雜查詢,包括bool查詢等等,推薦使用

    /*查詢匹配非常漂亮的人或則年齡在90以上的*/
    
    //構建NativeSearchQuery建造器
    NativeSearchQueryBuilder nsqb = new NativeSearchQueryBuilder();
    //構造Bool查詢條件		
    BoolQueryBuilder bqb = new BoolQueryBuilder();
    //通過該Bool查詢器構建should查詢器
    List<QueryBuilder> should = bqb.should();
    //向should里面添加兩個查詢條件
    should.add(new MatchQueryBuilder("desc", "非常漂亮的人"));
    should.add(new RangeQueryBuilder("age").gt(90));
    //注冊bool查詢條件
    nsqb.withQuery(bqb);
    //注冊分頁(第一頁,顯示3條)
    nsqb.withPageable(PageRequest.of(0, 3));
    //注冊排序(age降序)
    nsqb.withSort(SortBuilders.fieldSort("age").order(SortOrder.DESC));
    //構建NativeSearchQuery
    NativeSearchQuery nsq = nsqb.build();
    //執行查詢方法		
    SearchHits<Student> shs = operations.search(nsq, Student.class);
    System.out.println(shs.getTotalHits());
    shs.getSearchHits().forEach(x -> {
    	Student stu = x.getContent();
    	System.out.println(stu.getName()+":"+stu.getDesc()+":"+stu.getAge());
    });
    

    查詢結果高亮顯示

    //創建高亮顯示幕
    HighlightBuilder hb = new HighlightBuilder();
    //設定高亮欄位
    hb.field("desc");
    //設定為false,匹配欄位都會高亮顯示
    hb.requireFieldMatch(false);
    //設定如何高亮顯示
    hb.preTags("<span style=\"color:red\">");
    hb.postTags("</span>");
    //設定高亮顯示范圍以字符為單位
    hb.fragmentSize(800);
    //設定高亮顯示的開始位置
    hb.numOfFragments(0);
    		
    NativeSearchQueryBuilder nsqb = new NativeSearchQueryBuilder();
    //注冊高亮顯示幕
    nsqb.withHighlightBuilder(hb);
    nsqb.withQuery(new MatchQueryBuilder("desc", "非常漂亮"));
    NativeSearchQuery nsq = nsqb.build();
    SearchHits<Student> shs = operations.search(nsq, Student.class);
    shs.getSearchHits().forEach(x -> {
    	Student stu = x.getContent();
        String desc = stu.getDesc();
        //獲取高亮顯示欄位
    	List<String> hs = x.getHighlightField("desc"); 
    	if(hs != null && hs.size() > 0) desc = hs.get(0);
    	System.out.println(stu.getName()+":"+desc);
    });
    

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/258916.html

標籤:其他

上一篇:高可用RabbitMQ集群的搭建及原理分析

下一篇:“ 我向你奔赴而來,你就是星辰大海 “

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more