Elasticsearchネストタイプnested
19410 ワード
1.背景紹介
Elasticsearchを検索エンジンとして使用すると、domainにまたがって検索するシーンに遭遇する可能性があります.例えば、学生のカリキュラム管理システムを作ったり、学生の名前を探したりして、その学生の選択状況を知っているようです.
もちろん問題を解決する方法はたくさんあります.私は学生を探して、dbに行って学生関連の選択科目を探して、すべての課程を調べることができます.時にはデータ量が大きくなく、私のインデックスが1つの課程次元しかない場合、ネストタイプを使ってこのような問題を解決する必要があります.本文はesとkibinaを使用してインスタンスを操作する.中国語のインスタンスに基づいてik分詞器も使用されているため、具体的には以下の参照ができる.
Elasticsearchのインストールと使用
ElasticsearchでのIK分詞器の使用
2.オブジェクトタイプ
Elasticsearchはオブジェクトタイプのストレージをサポートし、あるdocumentのフィールドにオブジェクト配列を格納することができます.例えば、カリキュラムをdocumentとして使用すると、このカリキュラムはstudentsフィールドを確立し、そのカリキュラムの下の学生object配列を格納することができます.
Elasticsearchで、次のようなclassを新規作成します.testインデックス.studentがobject配列タイプである.
classへtestはデータを入れて、今インデックスの中に全部で2つのデータがあります
次に、クエリー文を使用してインデックスをクエリーできます.idが1の学生が参照する授業を検索すると、数学の授業を調べることができます.
張三という名前の学生が参加した授業を調べると、数学の授業も調べることができます.
しかし、idが1で、李四という名前の学生が参加した授業を調べると
私たちは、出た結果も数学の授業であることを発見しました.これは少しおかしいです.idが1で、名前が李四の学生は一人もいないので、このような授業はあるべきではありません.これはどういうことですか.もともとes内部ではobject配列タイプが平らになりますが、簡単に言えば入力した配列です.実際に格納されているタイプは:
インデックスの作成も、このような平らな論理に基づいています.このとき,Elasticsearch内のネストタイプを用いて問題を解決することができる.
3.Nestedタイプ
2と同様に、classという名前のテストインデックスを作成する必要があります.studentにはtypeフィールドがあり、「type」:「nested」とは異なります.
同じデータをインポートし、検索idが1で、名前が李四の学生の授業を使用します.このとき、検索結果が空です.
4.その他の方式
このdomainにまたがる検索を解決するには、ネストされたタイプに対してElasticsearchのパフォーマンスを非常に消費する他の方法があります.検索フィールドの値を1つのフィールドに平らに保存するか、学生にインデックスを個別に作成してから、学生-クラスマッピングリレーションシップテーブルに行ってクラスを検索することができます.この辺りは後で紹介する機会があります.
転載先:https://juejin.im/post/5cf3cd576fb9a07ec56e6184
Elasticsearchを検索エンジンとして使用すると、domainにまたがって検索するシーンに遭遇する可能性があります.例えば、学生のカリキュラム管理システムを作ったり、学生の名前を探したりして、その学生の選択状況を知っているようです.
もちろん問題を解決する方法はたくさんあります.私は学生を探して、dbに行って学生関連の選択科目を探して、すべての課程を調べることができます.時にはデータ量が大きくなく、私のインデックスが1つの課程次元しかない場合、ネストタイプを使ってこのような問題を解決する必要があります.本文はesとkibinaを使用してインスタンスを操作する.中国語のインスタンスに基づいてik分詞器も使用されているため、具体的には以下の参照ができる.
Elasticsearchのインストールと使用
ElasticsearchでのIK分詞器の使用
2.オブジェクトタイプ
Elasticsearchはオブジェクトタイプのストレージをサポートし、あるdocumentのフィールドにオブジェクト配列を格納することができます.例えば、カリキュラムをdocumentとして使用すると、このカリキュラムはstudentsフィールドを確立し、そのカリキュラムの下の学生object配列を格納することができます.
Elasticsearchで、次のようなclassを新規作成します.testインデックス.studentがobject配列タイプである.
PUT /class_test
{
"mappings":{
"class_test": {
"properties": {
"id": {
"type": "keyword"
},
"name": {
"analyzer": "ik_max_word",
"type": "text"
},
"type":{
"type":"keyword"
},
"student":{
"properties": {
"name":{
"analyzer": "ik_max_word",
"type": "text"
},
"id":{
"type":"keyword"
}
}
}
}
}
},
"settings":{
"index": {
"refresh_interval": "1s",
"number_of_shards": 5,
"max_result_window": "10000000",
"mapper": {
"dynamic": "false"
},
"number_of_replicas": 0
}
}
}
classへtestはデータを入れて、今インデックスの中に全部で2つのデータがあります
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "class_test",
"_type" : "class_test",
"_id" : "ijfJ5GoBJeNZPNCWykLR",
"_score" : 1.0,
"_source" : {
"id" : "1",
"name" : " ",
"student" : [
{
"id" : "1",
"name" : " "
},
{
"id" : "2",
"name" : " "
}
]
}
},
{
"_index" : "class_test",
"_type" : "class_test",
"_id" : "Q9NxGGsBa-TqHCWqAaM4",
"_score" : 1.0,
"_source" : {
"id" : "2",
"name" : " ",
"student" : [
{
"id" : "3",
"name" : " "
},
{
"id" : "4",
"name" : " "
}
]
}
}
]
}
}
次に、クエリー文を使用してインデックスをクエリーできます.idが1の学生が参照する授業を検索すると、数学の授業を調べることができます.
GET /class_test/class_test/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"student.id": "1"
}
}
]
}
}
}
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "class_test",
"_type" : "class_test",
"_id" : "ijfJ5GoBJeNZPNCWykLR",
"_score" : 0.2876821,
"_source" : {
"id" : "1",
"name" : " ",
"student" : [
{
"id" : "1",
"name" : " "
},
{
"id" : "2",
"name" : " "
}
]
}
}
]
}
}
張三という名前の学生が参加した授業を調べると、数学の授業も調べることができます.
GET /class_test/class_test/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"student.name": " "
}
}
]
}
}
}
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "class_test",
"_type" : "class_test",
"_id" : "ijfJ5GoBJeNZPNCWykLR",
"_score" : 0.5753642,
"_source" : {
"id" : "1",
"name" : " ",
"student" : [
{
"id" : "1",
"name" : " "
},
{
"id" : "2",
"name" : " "
}
]
}
}
]
}
}
しかし、idが1で、李四という名前の学生が参加した授業を調べると
GET /class_test/class_test/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"student.name": " "
}
},
{
"match": {
"student.id": "1"
}
}
]
}
}
}
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.8630463,
"hits" : [
{
"_index" : "class_test",
"_type" : "class_test",
"_id" : "ijfJ5GoBJeNZPNCWykLR",
"_score" : 0.8630463,
"_source" : {
"id" : "1",
"name" : " ",
"student" : [
{
"id" : "1",
"name" : " "
},
{
"id" : "2",
"name" : " "
}
]
}
}
]
}
}
私たちは、出た結果も数学の授業であることを発見しました.これは少しおかしいです.idが1で、名前が李四の学生は一人もいないので、このような授業はあるべきではありません.これはどういうことですか.もともとes内部ではobject配列タイプが平らになりますが、簡単に言えば入力した配列です.実際に格納されているタイプは:
"student.id":[1,2],
"student.name":[ , ]
インデックスの作成も、このような平らな論理に基づいています.このとき,Elasticsearch内のネストタイプを用いて問題を解決することができる.
3.Nestedタイプ
2と同様に、classという名前のテストインデックスを作成する必要があります.studentにはtypeフィールドがあり、「type」:「nested」とは異なります.
PUT /class
{
"mappings":{
"class": {
"properties": {
"id": {
"type": "keyword"
},
"name": {
"analyzer": "ik_max_word",
"type": "text"
},
"type":{
"type":"keyword"
},
"student":{
"type":"nested",
"properties": {
"name":{
"analyzer": "ik_max_word",
"type": "text"
},
"id":{
"type":"keyword"
}
}
}
}
}
},
"settings":{
"index": {
"refresh_interval": "1s",
"number_of_shards": 5,
"max_result_window": "10000000",
"mapper": {
"dynamic": "false"
},
"number_of_replicas": 0
}
}
}
同じデータをインポートし、検索idが1で、名前が李四の学生の授業を使用します.このとき、検索結果が空です.
GET /class/class/_search
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "student",
"query": {
"bool": {"must": [
{
"match": {
"student.name": " "
}
},
{
"match": {
"student.id": "1"
}
}
]}
}
}
}
]
}
}
}
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}
4.その他の方式
このdomainにまたがる検索を解決するには、ネストされたタイプに対してElasticsearchのパフォーマンスを非常に消費する他の方法があります.検索フィールドの値を1つのフィールドに平らに保存するか、学生にインデックスを個別に作成してから、学生-クラスマッピングリレーションシップテーブルに行ってクラスを検索することができます.この辺りは後で紹介する機会があります.
転載先:https://juejin.im/post/5cf3cd576fb9a07ec56e6184