国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Elasticsearch_分詞器、搜索文檔以及原生JAVA操作

這篇具有很好參考價值的文章主要介紹了Elasticsearch_分詞器、搜索文檔以及原生JAVA操作。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

一、ES分詞器

1、默認分詞器

ES文檔的數(shù)據(jù)拆分成一個個有完整含義的關鍵詞,并將關鍵詞與文檔對應,這樣就可以通過關鍵詞查詢文檔。要想正確的分詞,需要選擇合適的分詞器。
standard analyzer:Elasticsearch的默認分詞器,根據(jù)空格和標點符號對應英文進行分詞,會進行單詞的大小寫轉換。
默認分詞器是英文分詞器,對中文是一字一詞。

  1. 測試默認分詞器的效果

    GET /_analyze
    {
      "text":"z z x",
      "analyzer": "standard"
    }
    
    

2、IK分詞器

2.1 IK分詞器安裝及測試

IK分詞器提供了兩種算法:
1)ik_smart:最少切分
2)ik_max_word:最細粒度劃分

  1. 關閉docker容器中的ES服務和kibana:docker stop elasticsearch,docker stop kibana

  2. 下載IKAnalyzer:https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v8.6.1/elasticsearch-analysis-ik-8.6.1.zip

  3. 通過mobax上傳至虛擬機的目錄/,然后進行解壓縮:unzip elasticsearch-analysis-ik-8.6.1.zip -d /usr/local/elasticsearch/plugins/analysis-ik

  4. 切換至es用戶:su es

  5. 進入bin目錄:cd /usr/local/elasticsearch/bin

  6. 啟動ES服務并在后臺運行:./elasticsearch -d

  7. 切換到kibana的bin目錄:cd ../../kibana-8.6.1/bin/

  8. 啟動kibana:./kibana

  9. 測試IK分詞器ik_smart(最少切分)

    GET /_analyze
    {
      "text":"我是要成為海賊王的男人",
      "analyzer": "ik_smart"
    }
    

    即一段話中的字只會被劃分一次

  10. 測試IK分詞器ik_max_word(最細粒度劃分)

    GET /_analyze
    {
      "text":"我是要成為海賊王的男人",
      "analyzer": "ik_max_word"
    }
    

    即一段話中的字可能會被劃分多次

2.2 IK分詞器詞典

IK分詞器根據(jù)詞典進行分詞,詞典文件在IK分詞器的config目錄中。
main.dic:IK中內置的詞典。記錄了IK統(tǒng)計的所有中文單詞。
IKAnalyzer.cfg.xml:用于配置自定義詞庫。

  1. 進入到IK分詞器的配置目錄:cd /usr/local/elasticsearch/plugins/analysis-ik/config

  2. 切換root用戶進行修改:su root

  3. 修改配置文件:vim IKAnalyzer.cfg.xml,修改如下:

    <entry key="ext_dict">ext_dict.dic</entry>
    <entry key="ext_stopwords">ext_stopwords.dic</entry>
    
  4. 創(chuàng)建并編輯擴展詞:vim ext_dict.dic,添加如下:

    率土之濱
    

    此時率土之濱會被分成一個詞。

  5. 創(chuàng)建并編輯停用詞:vim ext_stopwords.dic,添加如下

    率土
    

    此時率土不會被分成一個詞。

  6. 切換到es用戶:su es

  7. 重啟ES服務
    1)找到對應的進程id:ps -ef |grep elastic
    2)根據(jù)id殺死該進程:kill -9 ID號
    3)進入到elasticsearch的bin目錄:cd /usr/local/elasticsearch/bin
    4)啟動ES服務:./elasticsearch -d

  8. 重啟kibana服務
    1)找到對應的進程id:netstat -anp | grep 5601
    2)根據(jù)id殺死該進程:kill -9 ID號
    3)進入到kibana的bin目錄:cd ../../kibana-8.6.1/bin/
    4)重啟kibana服務:./kibana

3、拼音分詞器

  1. 下載拼音分詞器:https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v8.6.1/elasticsearch-analysis-pinyin-8.6.1.zip

  2. 通過mobax上傳到虛擬機的/目錄,解壓到elasticsearch的plugins/analysis-pinyin目錄下:unzip elasticsearch-analysis-pinyin-8.6.1.zip -d /usr/local/elasticsearch/plugins/analysis-pinyin

  3. 切換到es用戶:su es

  4. 重啟ES服務
    1)找到對應的進程id:ps -ef |grep elastic
    2)根據(jù)id殺死該進程:kill -9 ID號
    3)進入到elasticsearch的bin目錄:cd /usr/local/elasticsearch/bin
    4)啟動ES服務:./elasticsearch -d

  5. 重啟kibana服務
    1)找到對應的進程id:netstat -anp | grep 5601
    2)根據(jù)id殺死該進程:kill -9 ID號
    3)進入到kibana的bin目錄:cd ../../kibana-8.6.1/bin/
    4)重啟kibana服務:./kibana

  6. 測試拼音分詞器

    GET /_analyze
    {
      "text":"我是要成為海賊王的男人",
      "analyzer": "pinyin"
    }
    

4、自定義分詞器

需要對一段內容既進行文字分詞,又進行拼音分詞,此時需要自定義ik+pinyin分詞器。

  1. 在創(chuàng)建索引時設置自定義分詞器

    PUT student3
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "ik_pinyin":{//自定義分詞器名
              "tokenizer":"ik_max_word",//基本分詞器
              "filter":"pinyin_filter"//配置過濾分詞器
            }
          },
          "filter": {
            "pinyin_filter":{
              "type":"pinyin",//另一個分詞器
              "keep_separete_first_letter":false,//是否分詞每個字的首字母
              "keep_full_pinyin":true,//是否全拼分詞
              "keep_original":true,//是否保留原始輸入
              "remove_duplicated_term":true//是否刪除重復項
            }
          }
        }
      },
      "mappings": {
        "properties": {
          "age":{
            "type": "integer"
          },
          "name":{
            "type": "text",
            "store": true,
            "index": true,
            "analyzer": "ik_pinyin"
          }
        }
      }
    }
    

    即在ik分詞器分詞后,再用拼音分詞器進行分詞。

  2. 測試自定義分詞器ik+pinyin

    GET /student3/_analyze
    {
      "text":"我是要成為海賊王的男人",
      "analyzer": "ik_pinyin"
    }
    

    “keep_separete_first_letter”:false,所以沒有wsycwhzwdnr這一段首字母拼音。
    “keep_full_pinyin”:true,所以每個字的全拼都會被分詞。
    “keep_original”:true,所以ik分詞器分詞后的結果也還在。
    “remove_duplicated_term”:true,所以分詞器分詞后顯示的結果不會重復。

二、搜索文檔

1、添加文檔數(shù)據(jù)

  1. 創(chuàng)建students索引

    PUT /students
    {
      "mappings": {
        "properties": {
          "id": {
            "type": "integer",
            "index": true
          },
          "name": {
            "type": "text",
            "store": true,
            "index": true,
            "analyzer": "ik_smart"
          },
          "info": {
            "type": "text",
            "store": true,
            "index": true,
            "analyzer": "ik_smart"
          }
        }
      }
    }
    
  2. 在students索引中創(chuàng)建文檔

    POST /students/_doc
    {
      "id":1,
      "name":"羚羊王子",
      "info":"阿里嘎多美羊羊桑"
    }
    POST /students/_doc
    {
      "id":2,
      "name":"沸羊羊",
      "info":"吃阿里嘎多美羊羊桑"
    }
    POST /students/_doc
    {
      "id":3,
      "name":"美羊羊",
      "info":"沸羊羊,你八嘎呀lua"
    }
    POST /students/_doc
    {
      "id":4,
      "name":"李青",
      "info":"一庫一庫"
    }
    POST /students/_doc
    {
      "id":5,
      "name":"亞索",
      "info":"面對疾風吧"
    }
    

2、搜索方式

  1. 查詢所有文檔

    GET /students/_search
    {
      "query": {
        "match_all": {}
      }
    }
    
  2. 將查詢條件分詞后再進行搜索

    GET /students/_search
    {
      "query": {
        "match": {
          "info":"阿里嘎多"
        }
      }
    }
    

    即將跟分詞后的結果,一個一個進行搜索。

  3. ES糾錯功能(即模糊查詢)

    GET /students/_search
    {
      "query": {
        "match": {
          "info":{
            "query": "lue",
            "fuzziness": 1//最多錯誤字符數(shù),不能超過2
          }
        }
      }
    }
    
    

使用match方式可以實現(xiàn)模糊查詢,但是模糊查詢對中文的支持效果一般。

  1. 對數(shù)字類型的字段進行范圍搜索

    GET /students/_search
    {
      "query": {
        "range": {
          "id": {
            "gte": 1,
            "lte": 3
          }
        }
      }
    }
    

    此時gt是大于,lt是小于,后面的e是等于。

  2. 短語檢索,搜索條件不做任何分詞解析,在搜索字段對應的倒排索引中精確匹配。

    GET /students/_search
    {
      "query": {
        "match_phrase": {
          "info": "八嘎"
        }
      }
    }
    

    它用于關鍵詞檢索,但是得是分詞器認為是關鍵詞才算是關鍵詞,例如美羊羊就不算,但是沸羊羊就算。也可以在ik的擴展詞文件中去設置關鍵詞。

  3. 單詞/詞組搜索。搜索條件不做任何分詞解析,在搜索字段對應的倒排索引中精確匹配。
    1)單詞搜索

    GET /students/_search
    {
      "query": {
        "term": {
          "info": "疾風"
        }
      }
    }
    

    單詞搜索時跟短語檢索很像。但是此時沸羊羊在單詞這邊查詢不到,估計是單詞時,條件的字符數(shù)不超過2個。
    2)詞組搜索

    GET /students/_search
    {
      "query": {
        "terms": {
          "info": ["疾風","沸"]
        }
      }
    }
    

    可以多個單詞分別作為條件同時搜索。

  4. 復合搜索
    1)must,多個搜索方式必須都滿足

    GET /students/_search
    {
      "query": {
        "bool": {
          "must": [
            {
             "term":{
                "info": "嘎"
              }
            },
            { 
              "range": {
               "id": {
                  "gte": 2,
                  "lte": 4
                }
              }
            }
          ]
        }
      }
    }
    

    2)should,多個搜索方式任意滿足一個

    GET /students/_search
    {
      "query": {
        "bool": {
          "should": [
            {
             "term":{
                "info": "嘎"
              }
            },
            { 
              "range": {
               "id": {
                  "gte": 2,
                  "lte": 4
                }
              }
            }
          ]
        }
      }
    }
    

    3)must_not,多個搜索方式都必須不滿足

    GET /students/_search
    {
      "query": {
        "bool": {
          "must": [
            {
             "term":{
                "info": "嘎"
              }
            }
          ],
          "must_not": [
            { 
              "range": {
               "id": {
                  "gte": 1,
                  "lte": 2
                }
              }
            }
          ]
        }
      }
    }
    

3、ES搜索文檔的過濾處理

3.1 結果排序

  1. 默認排序,是根據(jù)查詢條件的匹配度分數(shù)進行排序的

    GET /students/_search
    {
      "query": {
        "match": {
          "info": "阿里噶多美羊羊桑"
        }
      }
    }
    
    
  2. 按照id進行升序排序

    GET /students/_search
    {
      "query": {
        "match": {
          "info": "阿里噶多美羊羊桑"
        }
      },
      "sort": [
        {
          "id": {
            "order": "asc"
          }
        }
      ]
    }
    
    

    降序則把asc改成desc。

3.2 分頁查詢

  1. 將查詢結果從from條開始(不包括from),到from+size條結束(包括from+size)

    GET /students/_search
    {
      "query": {
        "match_all": {}
      },
      "from": 0,
      "size": 2
    }
    

3.3 高亮查詢

  1. 為查詢的關鍵詞設置高亮,即在關鍵詞前面和后面加上后綴,再由前端的CS代碼設置。

    GET /students/_search
    {
      "query": {
        "match": {
          "info": "面對一庫阿里噶多美羊羊桑"
        }
      },
      "highlight": {
        "fields": {
          "info": {
            "fragment_size": 100,//返回高亮數(shù)據(jù)的最大長度
            "number_of_fragments": 5 //返回結果最多可以包含幾段不連續(xù)的文字
          }
        },
        "pre_tags": ["<em>"],
        "post_tags": ["</em>"]
      }
    }
    

3.4 SQL查詢

在ES7之后,支持SQL語句查詢文檔,但是只支持部分SQL語句。并且開源版本不支持Java操作SQL進行查詢。

  1. 使用簡單的SQL語句查詢文檔
    GET /_sql?format=txt
    {
      "query": "SELECT * FROM students"
    }
    

三、原生JAVA操作ES

1、搭建項目

  1. 創(chuàng)建一個空項目
    elasticsearch分詞器使用 java,分布式,elasticsearch,java,搜索引擎

  2. 在空項目下創(chuàng)建一個maven模塊
    elasticsearch分詞器使用 java,分布式,elasticsearch,java,搜索引擎

  3. 在maven模塊項目中的pom.xml文件中引入依賴

    <dependencies>
        <!--    es    -->
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.17.9</version>
        </dependency>
        <!--    es客戶端    -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.17.9</version>
        </dependency>
    
    
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>
    </dependencies>
    

    因為最新的客戶端只更新到8.0,但是好像不能用,只能用7.17.9版本。

2、索引操作

  1. 創(chuàng)建一個空索引

    //創(chuàng)建空索引
    @Test
    public void createIndex() throws IOException {
        //1.創(chuàng)建客戶端對象,連接ES
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.126.24", 9200, "http")));
        //2.創(chuàng)建請求對象
        CreateIndexRequest studentx = new CreateIndexRequest("studentx");
        //3.發(fā)送請求
        CreateIndexResponse response = client.indices().create(studentx, RequestOptions.DEFAULT);
        //4.操作響應結果
        System.out.println(response.index());
        //5.關閉客戶端
        client.close();
    }	    
    
  2. 給空索引添加結構

    //給索引添加結構
    @Test
    public void mappingIndex() throws IOException {
        //1.創(chuàng)建客戶端對象,連接ES
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.126.24", 9200, "http")));
        //2.創(chuàng)建請求對象
        PutMappingRequest request = new PutMappingRequest("studentx");
        request.source(" {\n" +
                "    \"properties\": {\n" +
                "      \"id\": {\n" +
                "        \"type\": \"integer\"\n" +
                "      },\n" +
                "      \"name\": {\n" +
                "        \"type\": \"text\"\n" +
                "      },\n" +
                "      \"age\": {\n" +
                "        \"type\": \"integer\"\n" +
                "      }\n" +
                "    }\n" +
                "  }", XContentType.JSON);
        //3.發(fā)送請求
        AcknowledgedResponse response = client.indices().putMapping(request, RequestOptions.DEFAULT);
        //4.操作響應結果
        System.out.println(response.isAcknowledged());
        //5.關閉客戶端
        client.close();
    }
    
  3. 刪除索引

    //刪除索引
    @Test
    public void deleteIndex() throws IOException {
        //1.創(chuàng)建客戶端對象,連接ES
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.126.24", 9200, "http")));
        //2.創(chuàng)建請求對象
        DeleteIndexRequest request = new DeleteIndexRequest("studentx");
        //3.發(fā)送請求
        AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
        //4.操作響應結果
        System.out.println(response.isAcknowledged());
        //5.關閉客戶端
        client.close();
    }
    

3、文檔操作

  1. 新增/修改文檔操作

    // 新增/修改文檔
    @Test
    public void addDocument() throws IOException {
        //1.創(chuàng)建客戶端對象,連接ES
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.126.24", 9200, "http")));
        //2.創(chuàng)建請求對象
        IndexRequest request = new IndexRequest("studentx").id("1");
        request.source(XContentFactory.jsonBuilder()
                .startObject()
                .field("id",1)
                .field("name","z z x")
                .field("age",18)
                .endObject());
        //3.發(fā)送請求
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        //4.操作響應結果
        System.out.println(response.status());
        //5.關閉客戶端
        client.close();
    }
    

    新增文檔成功,但是報了個錯Unable to parse response body for Response,意思是無法解析響應的正文。有可能是ES服務用的是8.6.1,但是JAVA依賴的版本是7.17.9,版本不一致導致的。

  2. 根據(jù)id查詢文檔

    // 根據(jù)id查詢文檔
    @Test
    public void findByIdDocument() throws IOException {
        //1.創(chuàng)建客戶端對象,連接ES
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.126.24", 9200, "http")));
        //2.創(chuàng)建請求對象
        GetRequest request = new GetRequest("studentx", "1");
        //3.發(fā)送請求
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        //4.操作響應結果
        System.out.println(response.getSourceAsString());
        //5.關閉客戶端
        client.close();
    }
    
  3. 刪除文檔

    // 刪除文檔
    @Test
    public void deleteDocument() throws IOException {
        //1.創(chuàng)建客戶端對象,連接ES
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.126.24", 9200, "http")));
        //2.創(chuàng)建請求對象
        DeleteRequest request = new DeleteRequest("studentx", "1");
        //3.發(fā)送請求
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        //4.操作響應結果
        System.out.println(response.status());
        //5.關閉客戶端
        client.close();
    }
    

4、搜索文檔

  1. 查找所有文檔

    // 搜索所有文檔
    @Test
    public void queryAllDocument() throws IOException {
        //1.創(chuàng)建客戶端對象,連接ES
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.126.24", 9200, "http")));
        //2.創(chuàng)建搜索條件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        //3.創(chuàng)建請求對象
        SearchRequest request = new SearchRequest("studentx").source(searchSourceBuilder);
        //4.發(fā)送請求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //5.操作響應結果
        SearchHits hits = response.getHits();
        for (SearchHit hit:hits) {
            System.out.println(hit.getSourceAsString());
        }
        //6.關閉客戶端
        client.close();
    }
    
  2. 根據(jù)關鍵詞搜索文檔文章來源地址http://www.zghlxwxcb.cn/news/detail-778398.html

    // 根據(jù)關鍵詞搜索文檔
    @Test
    public void queryTermDocument() throws IOException {
        //1.創(chuàng)建客戶端對象,連接ES
        RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(new HttpHost("192.168.126.24", 9200, "http")));
        //2.創(chuàng)建搜索條件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.termQuery("name","x"));
        //3.創(chuàng)建請求對象
        SearchRequest request = new SearchRequest("studentx").source(searchSourceBuilder);
        //4.發(fā)送請求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //5.操作響應結果
        SearchHits hits = response.getHits();
        for (SearchHit hit:hits) {
            System.out.println(hit.getSourceAsString());
        }
        //6.關閉客戶端
        client.close();
    }
    

總結:

  1. 1)默認分詞器是standard analyzer,是英文分詞器,根據(jù)空格和標點符號對應英文進行分詞,會進行單詞的大小寫轉換。
    2)IK分詞器,是中文分詞器,分別有兩種算法ik_smart:最少切分,即一段話中的字只會被劃分一次;ik_max_word:最細粒度劃分,即一段話中的字可能會被劃分多次。IK分詞器中可以在IKAnalyzer.cfg.xml文件中配置自定義詞庫,其中ext_stopwords是停用詞,即不使用;ext_dict是擴展詞,即使用。
    3)拼音分詞器,將中文進行轉換成拼音并且進行分詞。即單個文字以及整段文字的拼音進行分詞。
    4)自定義分詞器可以將ik和拼音分詞器進行一個組合,將ik分詞器分詞后的結果讓拼音分詞器再進行分詞。
  2. GET /students/_search,即GET + 索引+ _search是用來搜索文檔的固定格式。
    1)搜索方式有match_all,即搜索該索引全部的文檔。
    match,根據(jù)查詢條件分詞后,再按分詞的結果一個一個查詢,并且match可以實現(xiàn)模糊查詢,但是錯誤的字符數(shù)量不能超過兩個,使用fuzziness設置。
    range,對數(shù)字類型的字段進行范圍搜索,gt是大于,lt是小于,后面的e是等于。
    match_phrase,關鍵詞搜索,此時你的搜索條件要與分詞器分詞后的結果相同才會查詢到結構,并且它是精確搜索,不會再分詞。
    term是單詞搜索,條件的字符數(shù)不超過2個,也就是說可能match_phare的搜索范圍是包含term的。
    terms是詞組搜索,可以多個單詞分別作為條件同時搜索。
    復合搜索,must,多個搜索方式必須都滿足;should,多個搜索方式任意一個滿足;must_not,多個條件都必須不滿足。
  3. 由于ES對text類型字段數(shù)據(jù)會做分詞處理,使用哪個單詞做排序都是不合理的,所以ES中默認不允許text類型的字段做排序,可以使用keyword類型的字段作為排序依據(jù),因為keyword字段不做分詞處理。
    ES默認排序是按查詢條件的相關度分數(shù)排序,也可以使用sort,依據(jù)字段做升序和降序的排序。
    使用from和size進行分頁查詢,從from(不包括from)位置開始到from+size位置結束。
    highlight,為查詢的關鍵詞設置高亮,即在關鍵詞前面和后面加上后綴,再由前端的CS代碼設置。
    在ES7之后,支持SQL語句查詢文檔,但是只支持部分SQL語句。并且開源版本不支持Java操作SQL進行查詢。
  4. 原生JAVA操作ES時,索引操作時,使用CreateIndexRequest,PutMappingRequest,DeleteIndexRequest類進行索引的操作。
    文檔操作時,使用IndexRequest,GetRequest,DeleteRequest類進行文檔的操作。
    搜索文檔時,使用SearchRequest類進行搜索的操作。
    每次訪問ES時,都需要創(chuàng)建客戶端對象去連接ES,創(chuàng)建請求對象,發(fā)送請求到ES,然后ES返回一個響應,對這個響應進行處理,最后關閉這個客戶端。

到了這里,關于Elasticsearch_分詞器、搜索文檔以及原生JAVA操作的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包