<address id="tl19n"></address>
      <address id="tl19n"><nobr id="tl19n"></nobr></address>

        <address id="tl19n"></address>

          <address id="tl19n"></address>
          <form id="tl19n"></form>

              首頁 > 上網技巧 > 教你快速從SQL過度到Elasticsearch的DSL查詢

              教你快速從SQL過度到Elasticsearch的DSL查詢

              時間:2022-01-17 13:06 作者:QQ地帶 我要評論

              前言
              Elasticsearch太強大了,強大到跟python一樣,一種查詢能好幾種語法。其實我們用到的可能只是其中的一部分,比如:全文搜索。
              我們一般是會將mysql的部分字段導入到es,再查詢出相應的ID,再根據這些ID去數據庫找出來。
               
              問題來了:數據導入到es后,很多人都要面對這個es的json查詢語法,也叫DSL,如下
               
               
              于是一堆新詞來了,比如:filter、match、multi_match、query、term、range,容易讓沒學過的人抵觸。
               
              如果正常開發業務的程序員,只關心原先怎么用sql查詢出來的數據,在es中查詢出來。
              sql查詢定位,一般常用的是:=、!=、>、<、and、or、in、between等等。
               
              舉個例子,原先sql查詢一商品是這樣的
               
              SELECT * FROM goods WHERE spu_id = "wp123" OR ( spu_id = "wp345" AND min_price = 30 ) 
              對應到es是
               
              {
                "query": {
                  "bool": {
                    "should": [
                      {
                        "term": {
                          "spu_id": "wp123"
                        }
                      },
                      {
                        "bool": {
                          "must": [
                            {
                              "term": {
                                "spu_id": "wp345"
                              }
                            },
                            {
                              "term": {
                                "min_price": 30
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              }
              sql和dsl是有一定對應關系的,下面把一些常用的總結下,讓不熟悉es的童鞋能絲滑能從sql過度
               
              以下內容由chenqionghe傾情提供,祝您es使用愉快
               
              bool-相當于一個括號
              用bool包含起來的{},相當用()包含了一個復合查詢語句,如上邊的
               
              {
                "bool": {
                  "must": [
                    {
                      "term": {
                        "spu_id": "wp345"
                      }
                    },
                    {
                      "term": {
                        "min_price": 30
                      }
                    }
                  ]
                }
              }
              相當于
               
              看到沒有就是這么簡單
               
              should-相當于or
               
               
              must-相當于and
               
               
              must_not-相當于 ! and
              這個就相當于and取反了,
               
              例如:
               
              SELECT  *  FROM goods WHERE !(shop_id =79)
              相當于
               
              {
                "query": {
                  "bool": {
                    "must_not": [
                      {
                        "term": {
                          "shop_id": "79"
                        }
                      }
                    ]
                  }
                }
              }
              term-相當于=
              例如
               
              SELECT * FROM goods WHERE shop_id =79
              相當于
               
              {
                "query": {
                  "bool": {
                    "must": [
                      {
                        "term": {"shop_id": "79"}
                      }
                    ]
                  }
                }
              }
              terms-相當于in
              例如
               
              SELECT * FROM goods WHERE shop_id in (79,80,81)
              相當于
               
              {
                "query": {
                  "bool": {
                    "must": [
                      {
                        "terms": {
                          "shop_id": [79, 80, 81]
                        }
                      }
                    ]
                  }
                }
              }
              range-相當于between
              例如
               
              SELECT * FROM goods WHERE id between 1000 and 10005
              相當于
               
              {
                "query": {
                  "bool": {
                    "must": [
                      {
                        "range": {
                          "id": {
                            "gte": 1000,
                            "lte": 10005
                          }
                        }
                      }
                    ]
                  }
                }
              }
               
              exist相當于is not null
              例如
               
              SELECT * FROM goods WHERE id is not null
              相當于
               
              {
                "query": {
                  "bool": {
                    "must_not": [
                      {
                        "exists": {
                          "field": "id"
                        }
                      }
                    ]
                  }
                }
              }
              match-類似match...against
              這個match就相當于mysql的全文索引,關于mysql的全文索引,可以看一下這篇文章:從零開始學習MySQL全文索引
               
              舉個查詢的例子,我要搜索包含 "海南 2018"的詞,如下
              {
              "query": {
              "match": {
              "name": "海南 2018"
              }
              }
              }
              這相當于把所有的“海南”和“2018”記錄找出來了,他們是一個or的關系。如果想同時匹配怎么辦呢?
              可以這樣,指定一個operator,默認是用的"or",可以改成這樣
               
              {
                "query": {
                  "match": {
                    "name": {
                      "query": "海南 2018",
                      "operator": "and"
                    }
                  }
                }
              }
              includes-相當于select
              比如
               
              SELECT id,name FROM goods WHERE id = 1765
              相當于
               
              {
                "query": {
                  "bool": {
                    "must": [
                      {
                        "term": {
                          "id": 1765
                        }
                      }
                    ]
                  }
                },
                "_source":{"includes":["id","name"]}
              }
              sort-相當于order by
              比如
               
              SELECT * FROM goods ORDER BY id DESC 
              相當于
               
              {
              "sort": [
                {
                  "id": {
                    "order": "desc"
                  }
                }
              ]
              }
               
               
               
              from size-相當于limit
              例如
               
              SELECT * FROM goods ORDER BY id DESC LIMIT 5,2;
              相當于
               
              {
               "from": 5,
               "size": 2
              }
              到這里,差不多就已經可以絲滑地從sql過度到es的dsl了
               
              一些常見問題
              match和term的區別
              match在匹配時會對所查找的關鍵詞進行分詞,然后按分詞匹配查找,而term會直接對關鍵詞進行查找。一般模糊查找的時候,多用match
               
              query和filter的區別
              filter:只查詢出搜索條件的數據,不計算相關度分數
              query:查詢出搜索條件的數據,并計算相關度分數,按照分數進行倒序排序
              filter比query性能好,兩者可以一起使用
               
              filtered和filter區別
              filtered是比較老的的版本的語法,F在已經被bool替代,推薦使用bool。
              老版本寫法
               
              {
                "query": {
                  "filtered": {
                    "query": {
                      "match": {
                        "text": "quick brown fox"
                      }
                    },
                    "filter": {
                      "term": {
                        "status": "published"
                      }
                    }
                  }
                }
              }
              新版本寫法
               
              {
                "query": {
                  "bool": {
                    "must": {
                      "match": {
                        "text": "quick brown fox"
                      }
                    },
                    "filter": {
                      "term": {
                        "status": "published"
                      }
                    }
                  }
                }
              }
              filter兩種用法
              嵌套在bool下
               
              {
                "query": {
                  "bool": {
                    "must": {
                      "term": {
                        "term": {
                          "title": "kitchen3"
                        }
                      }
                    },
                    "filter": {
                      "term": {
                        "price": 1000
                      }
                    }
                  }
                }
              }
              在根目錄下使用
               
              {
                "query": {
                  "term": {
                    "title": "kitchen3"
                  }
                },
                "filter": {
                  "term": {
                    "price": 1000
                  }
                }
              }
              term和terms的區別
              term相當于where =
              terms相當于 where in (xx,xx,xx)
              如果想要=于多次,得用多個term,而不是terms
               
              如何高亮關鍵詞
              這里需要用到
              比如,我們查詢包含“海南”和“面試”的詞,match指定"海南 面試",highlight指定字段和要包含的標簽
               
              GET /goods-search-v20210511/_search
              {
                "query": {
                  "match": {
                    "name": "海南 面試"
                  }
                },
                "highlight": {
                  "fields": {
                    "name": {
                      "pre_tags": [
                      "<cheniqonghe>"
                    ], 
                    "post_tags": [
                      "</cheniqonghe>"
                    ]
                    }
                  }
                },
                "_source":{"includes":["id","name"]}
              查詢結果如下
               
              可以看到es已經將關鍵詞用指定的標簽包起來了

              標簽: SQL
              頂一下
              (0)
              0%
              踩一下
              (0)
              0%

              Google提供的廣告

              国产古代一级a毛片,国产成人午夜在线直播,write.as 当众老师
                <address id="tl19n"></address>
                  <address id="tl19n"><nobr id="tl19n"></nobr></address>

                    <address id="tl19n"></address>

                      <address id="tl19n"></address>
                      <form id="tl19n"></form>