當前位置:網站首頁>ES-查詢相關和IK分詞器

ES-查詢相關和IK分詞器

2022-01-27 06:42:53 A1L__

排序查詢

創建數據

PUT books/_doc/1
{
    
  "name":"顧老二",
  "age":30,
  "from": "gu",
  "desc": "皮膚黑、武器長、性格直",
  "tags": ["黑", "長", "直"]
}

PUT books/_doc/2
{
    
  "name":"大娘子",
  "age":18,
  "from":"sheng",
  "desc":"膚白貌美,嬌憨可愛",
  "tags":["白", "富","美"]
}

PUT books/_doc/3
{
    
  "name":"龍套偏房",
  "age":22,
  "from":"gu",
  "desc":"mmp,沒怎麼看,不知道怎麼形容",
  "tags":["造數據", "真","難"]
}


PUT books/_doc/4
{
    
  "name":"石頭",
  "age":29,
  "from":"gu",
  "desc":"粗中有細,狐假虎威",
  "tags":["粗", "大","猛"]
}

PUT books/_doc/5
{
    
  "name":"魏行首",
  "age":25,
  "from":"廣雲臺",
  "desc":"仿佛兮若輕雲之蔽月,飄飄兮若流風之回雪,mmp,最後竟然沒有嫁給顧老二!",
  "tags":["閉月","羞花"]
}

降序

2.1 降序:desc

想到排序,出現在腦海中的無非就是昇(正)序和降(倒)序。比如我們查詢顧府都有哪些人,並根據age字段按照降序,並且,我只想看nmaeage字段:

GET books/doc/_search
{
    
  "query": {
    
    "match": {
    
      "from": "gu"
    }
  },
  "sort": [
    {
    
      "age": {
    
        "order": "desc"
      }
    }
  ]
}

上例,在條件查詢的基礎上,我們又通過sort來做排序,根據age字段排序,是降序呢還是昇序,由order字段控制,desc是降序。

2.2 昇序:asc

那麼想要昇序怎麼搞呢?

GET books/doc/_search
{
    
  "query": {
    
    "match_all": {
    }
  },
  "sort": [  # 這是一個列錶,多個排序規則,往後再添加鍵值對就可以了,排序規則從上往下
    {
    
      "age": {
    
        "order": "asc"
      }
    }
  ]
}

上例,想要以昇序的方式排列,只需要將order值換為asc就可以了。

三 不是什麼數據類型都能排序

那麼,你可能會問,除了age,能不能以別的屬性作為排序條件啊?來試試:

結果跟我們想象的不一樣,報錯了!

注意:在排序的過程中,只能使用可排序的屬性進行排序。那麼可以排序的屬性有哪些呢?

  • 數字
  • 日期

其他的都不行!

分頁查詢

二 分頁查詢:from/size

我們來看看elasticsearch是怎麼將結果分頁的:

GET books/doc/_search
{
    
  "query": {
    
    "match_all": {
    }
  },
  "sort": [
    {
    
      "age": {
    
        "order": "desc"
      }
    }
  ], 
  "from": 2,
  "size": 1
}

上例,首先以age降序排序,查詢所有。並且在查詢的時候,添加兩個屬性fromsize來控制查詢結果集的數據條數。

  • from:從哪開始查
  • size:返回幾條結果
  • image-20210221131417107

上例中僅有一條數據,那是為啥呢?因為我們現在只有5條數據,從第4條開始查詢,就只有1條符合條件,所以,就返回了1條數據。

學到這裏,我們也可以看到,我們的查詢條件越來越多,開始僅是簡單查詢,慢慢增加條件查詢,增加排序,對返回結果進行限制。所以,我們可以說:對於elasticsearch來說,所有的條件都是可插拔的,彼此之間用,分割。比如說,我們在查詢中,僅對返回結果進行限制:

GET lqz/doc/_search
{
    
  "query": {
    
    "match_all": {
    }
  },
  "from": 4,
  "size": 2
}
# 這個的結果就是查詢所有然後從第五個開始選取兩條,沒超出限制的話

布爾查詢

一 前言

布爾查詢是最常用的組合查詢,根據子查詢的規則,只有當文檔滿足所有子查詢條件時,elasticsearch引擎才將結果返回。布爾查詢支持的子查詢條件共4中:

  • must(and)
  • should(or)
  • must_not(not)
  • filter

下面我們來看看每個子查詢條件都是怎麼玩的。

must

現在,我們用布爾查詢所有from屬性為gu的數據:

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "must": [
        {
    
          "match": {
    
            "from": "gu"
          }
        }
      ]
    }
  }
}

上例中,我們通過在bool屬性(字段)內使用must來作為查詢條件,那麼條件是什麼呢?條件同樣被match包圍,就是fromgu的所有數據。
這裏需要注意的是must字段對應的是個列錶,也就是說可以有多個並列的查詢條件,一個文檔滿足各個子條件後才最終返回。

結果如下:

{
    
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 3,
    "max_score" : 0.6931472,
    "hits" : [
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "4",
        "_score" : 0.6931472,
        "_source" : {
    
          "name" : "石頭",
          "age" : 29,
          "from" : "gu",
          "desc" : "粗中有細,狐假虎威",
          "tags" : [
            "粗",
            "大",
            "猛"
          ]
        }
      },
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
    
          "name" : "顧老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮膚黑、武器長、性格直",
          "tags" : [
            "黑",
            "長",
            "直"
          ]
        }
      },
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.2876821,
        "_source" : {
    
          "name" : "龍套偏房",
          "age" : 22,
          "from" : "gu",
          "desc" : "mmp,沒怎麼看,不知道怎麼形容",
          "tags" : [
            "造數據",
            "真",
            "難"
          ]
        }
      }
    ]
  }
}

上例中,可以看到,所有from屬性為gu的數據查詢出來了。

那麼,我們想要查詢fromgu,並且age30的數據怎麼搞呢?

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "must": [
        {
    
          "match": {
    
            "from": "gu"
          }
        },
        {
    
          "match": {
    
            "age": 30
          }
        }
      ]
    }
  }
}

上例中,在must列錶中,在增加一個age30的條件。

結果如下:

{
    
  "took" : 8,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 1,
    "max_score" : 1.287682,
    "hits" : [
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 1.287682,
        "_source" : {
    
          "name" : "顧老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮膚黑、武器長、性格直",
          "tags" : [
            "黑",
            "長",
            "直"
          ]
        }
      }
    ]
  }
}

上例,符合條件的數據被成功查詢出來了。

注意:現在你可能慢慢發現一個現象,所有屬性值為列錶的,都可以實現多個條件並列存在

should

那麼,如果要查詢只要是fromgu或者tags閉月的數據怎麼搞?

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "should": [
        {
    
          "match": {
    
            "from": "gu"
          }
        },
        {
    
          "match": {
    
            "tags": "閉月"
          }
        }
      ]
    }
  }
}

上例中,或關系的不能用must的了,而是要用should,只要符合其中一個條件就返回。

結果如下:

{
    
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 4,
    "max_score" : 0.6931472,
    "hits" : [
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "4",
        "_score" : 0.6931472,
        "_source" : {
    
          "name" : "石頭",
          "age" : 29,
          "from" : "gu",
          "desc" : "粗中有細,狐假虎威",
          "tags" : [
            "粗",
            "大",
            "猛"
          ]
        }
      },
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "5",
        "_score" : 0.5753642,
        "_source" : {
    
          "name" : "魏行首",
          "age" : 25,
          "from" : "廣雲臺",
          "desc" : "仿佛兮若輕雲之蔽月,飄飄兮若流風之回雪,mmp,最後竟然沒有嫁給顧老二!",
          "tags" : [
            "閉月",
            "羞花"
          ]
        }
      },
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
    
          "name" : "顧老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮膚黑、武器長、性格直",
          "tags" : [
            "黑",
            "長",
            "直"
          ]
        }
      },
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.2876821,
        "_source" : {
    
          "name" : "龍套偏房",
          "age" : 22,
          "from" : "gu",
          "desc" : "mmp,沒怎麼看,不知道怎麼形容",
          "tags" : [
            "造數據",
            "真",
            "難"
          ]
        }
      }
    ]
  }
}

返回了所有符合條件的結果。

must_not

那麼,如果我想要查詢from既不是gu並且tags也不是可愛,還有age不是18的數據怎麼辦?

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "must_not": [
        {
    
          "match": {
    
            "from": "gu"
          }
        },
        {
    
          "match": {
    
            "tags": "可愛"
          }
        },
        {
    
          "match": {
    
            "age": 18
          }
        }
      ]
    }
  }
}

上例中,mustshould都不能使用,而是使用must_not,又在內增加了一個age18的條件。

結果如下:

{
    
  "took" : 9,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
    
        "_index" : "books",
        "_type" : "doc",
        "_id" : "5",
        "_score" : 1.0,
        "_source" : {
    
          "name" : "魏行首",
          "age" : 25,
          "from" : "廣雲臺",
          "desc" : "仿佛兮若輕雲之蔽月,飄飄兮若流風之回雪,mmp,最後竟然沒有嫁給顧老二!",
          "tags" : [
            "閉月",
            "羞花"
          ]
        }
      }
    ]
  }
}

上例中,只有魏行首這一條數據,因為只有魏行首既不是顧家的人,標簽沒有可愛那一項,年齡也不等於18!
這裏有點需要補充,條件中age對應的18你寫成整形還是字符串都沒啥……

filter

那麼,如果要查詢fromguage大於25的數據怎麼查?

filter需要在bool內部,並且如果是and條件,需要用must,如果使用了should,會認為是should和filter是或者的關系

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "must": [
        {
    
          "match": {
    
            "from": "gu"
          }
        }
      ],
      "filter": {
    
        "range": {
    
          "age": {
    
            "gt": 25
          }
        }
      }
    }
  }
}

這裏就用到了filter條件過濾查詢,過濾條件的範圍用range錶示,gt錶示大於,大於多少呢?是25。

結果如下:

{
    
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 2,
    "max_score" : 0.6931472,
    "hits" : [
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "4",
        "_score" : 0.6931472,
        "_source" : {
    
          "name" : "石頭",
          "age" : 29,
          "from" : "gu",
          "desc" : "粗中有細,狐假虎威",
          "tags" : [
            "粗",
            "大",
            "猛"
          ]
        }
      },
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
    
          "name" : "顧老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮膚黑、武器長、性格直",
          "tags" : [
            "黑",
            "長",
            "直"
          ]
        }
      }
    ]
  }
}

上例中,age大於25的條件都已經篩選出來了。

那麼要查詢fromguage大於等於30的數據呢?

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "must": [
        {
    
          "match": {
    
            "from": "gu"
          }
        }
      ],
      "filter": {
    
        "range": {
    
          "age": {
    
            "gte": 30
          }
        }
      }
    }
  }
}

上例中,大於等於用gte錶示。

結果如下:

{
    
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 1,
    "max_score" : 0.2876821,
    "hits" : [
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
    
          "name" : "顧老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮膚黑、武器長、性格直",
          "tags" : [
            "黑",
            "長",
            "直"
          ]
        }
      }
    ]
  }
}

那麼,要查詢age小於25的呢?

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "filter": {
    
        "range": {
    
          "age": {
    
            "lt": 25
          }
        }
      }
    }
  }
}

上例中,小於用lt錶示,結果如下:

{
    
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 2,
    "max_score" : 0.0,
    "hits" : [
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.0,
        "_source" : {
    
          "name" : "大娘子",
          "age" : 18,
          "from" : "sheng",
          "desc" : "膚白貌美,嬌憨可愛",
          "tags" : [
            "白",
            "富",
            "美"
          ]
        }
      },
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.0,
        "_source" : {
    
          "name" : "龍套偏房",
          "age" : 22,
          "from" : "gu",
          "desc" : "mmp,沒怎麼看,不知道怎麼形容",
          "tags" : [
            "造數據",
            "真",
            "難"
          ]
        }
      }
    ]
  }
}

在查詢一個age小於等於18的怎麼辦呢?

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "filter": {
    
        "range": {
    
          "age": {
    
            "lte": 18
          }
        }
      }
    }
  }
}

上例中,小於等於用lte錶示。結果如下:

{
    
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 1,
    "max_score" : 0.0,
    "hits" : [
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.0,
        "_source" : {
    
          "name" : "大娘子",
          "age" : 18,
          "from" : "sheng",
          "desc" : "膚白貌美,嬌憨可愛",
          "tags" : [
            "白",
            "富",
            "美"
          ]
        }
      }
    ]
  }
}

要查詢fromguage25~30之間的怎麼查?

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "must": [
        {
    
          "match": {
    
            "from": "gu"
          }
        }
      ],
      "filter": {
    
        "range": {
    
          "age": {
    
            "gte": 25,
            "lte": 30
          }
        }
      }
    }
  }
}

上例中,使用ltegte來限定範圍。結果如下:

{
    
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 2,
    "max_score" : 0.6931472,
    "hits" : [
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "4",
        "_score" : 0.6931472,
        "_source" : {
    
          "name" : "石頭",
          "age" : 29,
          "from" : "gu",
          "desc" : "粗中有細,狐假虎威",
          "tags" : [
            "粗",
            "大",
            "猛"
          ]
        }
      },
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
    
          "name" : "顧老二",
          "age" : 30,
          "from" : "gu",
          "desc" : "皮膚黑、武器長、性格直",
          "tags" : [
            "黑",
            "長",
            "直"
          ]
        }
      }
    ]
  }
}

那麼,要查詢fromshengage小於等於25的怎麼查呢?其實結果,我們可能已經想到了,只有一條,因為只有盛家小六符合結果。

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "must": [
        {
    
          "match": {
    
            "from": "sheng"
          }
        }
      ],
      "filter": {
    
        "range": {
    
          "age": {
    
            "lte": 25
          }
        }
      }
    }
  }
}

結果果然不出灑家所料!

{
    
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 1,
    "max_score" : 0.6931472,
    "hits" : [
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.6931472,
        "_source" : {
    
          "name" : "大娘子",
          "age" : 18,
          "from" : "sheng",
          "desc" : "膚白貌美,嬌憨可愛",
          "tags" : [
            "白",
            "富",
            "美"
          ]
        }
      }
    ]
  }
}

但是,灑家手一抖,將must換為should看看會發生什麼?

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "should": [
        {
    
          "match": {
    
            "from": "sheng"
          }
        }
      ],
      "filter": {
    
        "range": {
    
          "age": {
    
            "lte": 25
          }
        }
      }
    }
  }
}

結果如下:

{
    
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    
    "total" : 3,
    "max_score" : 0.6931472,
    "hits" : [
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 0.6931472,
        "_source" : {
    
          "name" : "大娘子",
          "age" : 18,
          "from" : "sheng",
          "desc" : "膚白貌美,嬌憨可愛",
          "tags" : [
            "白",
            "富",
            "美"
          ]
        }
      },
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "5",
        "_score" : 0.0,
        "_source" : {
    
          "name" : "魏行首",
          "age" : 25,
          "from" : "廣雲臺",
          "desc" : "仿佛兮若輕雲之蔽月,飄飄兮若流風之回雪,mmp,最後竟然沒有嫁給顧老二!",
          "tags" : [
            "閉月",
            "羞花"
          ]
        }
      },
      {
    
        "_index" : "lqz",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.0,
        "_source" : {
    
          "name" : "龍套偏房",
          "age" : 22,
          "from" : "gu",
          "desc" : "mmp,沒怎麼看,不知道怎麼形容",
          "tags" : [
            "造數據",
            "真",
            "難"
          ]
        }
      }
    ]
  }
}

結果有點出乎意料,因為龍套偏房和魏行首不屬於盛家,但也被查詢出來了。那你要問了,怎麼肥四?小老弟!這是因為在查詢過程中,優先經過filter過濾,因為should是或關系,龍套偏房和魏行首的年齡符合了filter過濾條件,也就被放行了!所以,如果在filter過濾條件中使用should的話,結果可能不會盡如人意!建議使用must代替

注意:filter工作於bool查詢內。比如我們將剛才的查詢條件改一下,把filterbool中挪出來。

GET lqz/doc/_search
{
    
  "query": {
    
    "bool": {
    
      "must": [
        {
    
          "match": {
    
            "from": "sheng"
          }
        }
      ]
    },
    "filter": {
    
      "range"{
    
        "age": {
    
          "lte": 25
        }
      }
    }
  }
}

如上例所示,我們將filterbool平級,看查詢結果:

{
    
  "error": {
    
    "root_cause": [
      {
    
        "type": "parsing_exception",
        "reason": "[bool] malformed query, expected [END_OBJECT] but found [FIELD_NAME]",
        "line": 12,
        "col": 5
      }
    ],
    "type": "parsing_exception",
    "reason": "[bool] malformed query, expected [END_OBJECT] but found [FIELD_NAME]",
    "line": 12,
    "col": 5
  },
  "status": 400
}

結果報錯了!所以,filter工作比特置很重要。

小結:

  • must:與關系,相當於關系型數據庫中的and
  • should:或關系,相當於關系型數據庫中的or
  • must_not:非關系,相當於關系型數據庫中的not
  • filter:過濾條件。
  • range:條件篩選範圍。
  • gt:大於,相當於關系型數據庫中的>
  • gte:大於等於,相當於關系型數據庫中的>=
  • lt:小於,相當於關系型數據庫中的<
  • lte:小於等於,相當於關系型數據庫中的<=

查詢結果 過濾:_source

在未來,一篇文檔可能有很多的字段,每次查詢都默認給我們返回全部,在數據量很大的時候,是的,比如我只想查姑娘的手機號,你一並給我個喜好啊、三圍什麼的算什麼?
所以,我們對結果做一些過濾,清清白白的告訴elasticsearch

GET books/doc/_search
{
    
  "query": {
    
    "match": {
    
      "name":"顧老二"
    }
  }
}

GET books/doc/_search
{
    
  "query": {
    
    "match": {
    
      "name":"顧老二"
    }
  },
  "_source": ["name","age"]
}

image-20210221141046275

image-20210221140927221

高亮顯示

如果返回的結果集中很多符合條件的結果,那怎麼能一眼就能看到我們想要的那個結果呢?比如下面網站所示的那樣,我們搜索elasticsearch,在結果集中,將所有elasticsearch高亮顯示?

image-20210221141335318

如上圖我們搜索一樣。我們該怎麼做呢?

GET books/doc/_search
{
    
  "query": {
    
    "match": {
    
      "tags": "粗"
    }
  },
  "highlight": {
    
  "fields": {
    
    "from":{
    },
    "tags":{
    }
  }
  }
}

上例中,我們使用highlight屬性來實現結果高亮顯示,需要的字段名稱添加到fields內即可,elasticsearch會自動幫我們實現高亮。

image-20210221142113832

自定義高亮顯示

但是,你可能會問,我不想用em標簽, 我這麼牛逼,應該用個b標簽啊!好的,elasticsearch同樣考慮到你很牛逼,所以,我們可以自定義標簽。

GET books/doc/_search
{
    
  "query": {
    
    "match": {
    
      "from": "gu"
    }
  },
  "highlight": {
    
    "pre_tags": "<b class='key' style='color:red'>",  # 在結果之前
    "post_tags": "</b>",  # 在結果之後
    "fields": {
    
      "from": {
    }
    }
  }
}

上例中,在highlight中,pre_tags用來實現我們的自定義標簽的前半部分,在這裏,我們也可以為自定義的標簽添加屬性和樣式。post_tags實現標簽的後半部分,組成一個完整的標簽。至於標簽中的內容,則還是交給fields來完成。

image-20210221142602857

聚合函數

聚合函數大家都不陌生,elasticsearch中也沒玩出新花樣,所以,這一章相對簡單,只需要記得:

  • avg
  • max
  • min
  • sum

以及各自的用法即可。先來看求平均。

svg

GET books/doc/_search
{
    
  "query": {
    
    "match": {
    
      "from": "gu"
    }
  },
  "aggs": {
      # 聚合函數aggressive
    "my_avg": {
      # 結果別名
      "avg": {
      # 聚合方法
        "field": "age"  # 字段
      }
    }
  },
  "_source": ["name", "age"]  # 過濾
}

image-20210221143249371

max,min.sum

  "aggs": {
      # 聚合函數aggressive
    "my_max": {
      # 結果別名
      "max": {
      # 聚合方法
        "field": "age"  # 字段
      }
    }
  },
    "aggs": {
      # 聚合函數aggressive
    "my_min": {
      # 結果別名
      "min": {
      # 聚合方法
        "field": "age"  # 字段
      }
    }
  },
    "aggs": {
      # 聚合函數aggressive
    "my_sum": {
      # 結果別名
      "sum": {
      # 聚合方法
        "field": "age"  # 字段
      }
    }
  },

分組查詢

現在我想要查詢所有人的年齡段,並且按照15~20,20~25,25~30分組,並且算出每組的平均年齡。

分析需求,首先我們應該先把分組做出來。

GET books/doc/_search
{
    
  "size": 0, 
  "query": {
    
    "match_all": {
    }
  },
  "aggs": {
    
    "age_group": {
    
      "range": {
    
        "field": "age",
        "ranges": [
          {
    
            "from": 15,
            "to": 20
          },
          {
    
            "from": 20,
            "to": 25
          },
          {
    
            "from": 25,
            "to": 30
          }
        ]
      }
    }
  }
}

上例中,在aggs的自定義別名age_group中,使用range來做分組,field是以age為分組,分組使用ranges來做,fromto是範圍,我們根據需求做出三組。

現在我想要查詢所有人的年齡段,並且按照15~20,20~25,25~30分組,並且算出每組的平均年齡。

分析需求,首先我們應該先把分組做出來。

image-20210221150503276

返回的結果中可以看到,已經拿到了三個分組。doc_count為該組內有幾條數據,此次共分為三組,查詢出4條內容。還有一條數據的age屬性值是30,不在分組的範圍內!

那麼接下來,我們就要對每個小組內的數據做平均年齡處理。

GET books/doc/_search
{
  "size": 0, 
  "query": {
    "match_all": {}
  },
  "aggs": {
    "age_group": {
      "range": {
        "field": "age",
        "ranges": [
          {
            "from": 15,
            "to": 20
          },
          {
            "from": 20,
            "to": 25
          },
          {
            "from": 25,
            "to": 30
          }
        ]
      },
      "aggs": {
        "my_avg": {
          "avg": {
            "field": "age"
          }
        }
      }
    }
  }
}

上例中,在分組下面,我們使用aggsage做平均數處理,這樣就可以了。

image-20210221150538583

在結果中,我們可以清晰的看到每組的平均年齡(my_avgvalue中)。

注意:聚合函數的使用,一定是先查出結果,然後對結果使用聚合函數做處理

小結:

  • avg:求平均
  • max:最大值
  • min:最小值
  • sum:求和

歡迎斧正,that’s all

IK中文分詞器

#1 github下載相應版本
https://github.com/medcl/elasticsearch-analysis-ik/releases?after=v7.5.2

2 解壓到es的plugin目錄下

3 重啟es

ik_max_word 和 ik_smart 什麼區別?

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

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

GET _analyze
{
    
  "analyzer": "ik_max_word",
  "text": "上海自來水來自海上"  
}
# text字段會分詞,keyword不會分詞。所以在建立i、映射關系(mapping)要先想好這個字段需不需要細分

image-20210221151905758

版權聲明
本文為[A1L__]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/01/202201270642529597.html

隨機推薦