Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
列表是一個接一個顯示條目的首選方式,而不是使用<br>標記。完整的列表定義包括開始和結束標記,以及表示列表中每個條目的標記。
有三種類型的列表:有序列表、無序列表和定義列表。
無序列表是一個帶條目符號的列表,類似于菜單。
無序列表 - <ul> ... </ul>
ul標記定義無序列表的開始和結束,列表項包含在ul標記中。
無序列表項 - <li> ... </li>
li標記添加每個條目的文本,每個列表項必須有自己的li標記。
符號類型 <ul type="disc | circle | square">
默認情況下,瀏覽器將顯示圓形條目符號。這可以通過使用ul標記的type屬性來更改,這將更改整個列表的條目符號類型。
條目符號類型 <li type="?">
通過設置li標記的type屬性,可以為列表中的某個條目設置不同的符號類型。
以下是無序列表的示例:
瀏覽器顯示內容如下所示:
對海量數據渲染,即使是強大的 Vue 也難免會遇到性能瓶頸,卡頓、掉幀等問題接踵而至。今天,我們就來聊聊如何利用虛擬列表這一“黑科技”,解決 Vue 中萬級數據列表的勾選卡頓問題,讓你的列表性能飛起來!
當數據量達到上萬條甚至更多時,傳統的列表渲染方式會將所有數據一次性加載并渲染到頁面上,這會帶來一系列問題:
虛擬列表的核心思想是:只渲染可視區域內的數據,非可視區域的數據不進行渲染,從而大大減少 DOM 節點數量,提高渲染效率。
<template>
<div class="virtual-list" @scroll="handleScroll">
<div class="list-viewport" :style="{ height: `${viewportHeight}px` }">
<div class="list-container" :style="{ transform: `translateY(${startIndex * itemHeight}px)` }">
<div v-for="(item, index) in visibleData" :key="index" class="list-item" :style="{ height: `${itemHeight}px` }">
<input type="checkbox" v-model="item.checked">
{{ item.label }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
dataList: [], // 所有數據
visibleData: [], // 可視區域數據
viewportHeight: 0, // 可視區域高度
itemHeight: 50, // 每個列表項高度
startIndex: 0, // 起始索引
endIndex: 0, // 結束索引
};
},
mounted() {
this.viewportHeight = this.$el.clientHeight;
this.generateData(10000); // 生成 10000 條數據
},
methods: {
// 生成模擬數據
generateData(count) {
for (let i = 0; i < count; i++) {
this.dataList.push({
label: `Item ${i}`,
checked: false,
});
}
this.updateVisibleData();
},
// 更新可視區域數據
updateVisibleData() {
this.startIndex = Math.floor(this.$el.scrollTop / this.itemHeight);
this.endIndex = Math.min(this.startIndex + Math.ceil(this.viewportHeight / this.itemHeight) + 1, this.dataList.length);
this.visibleData = this.dataList.slice(this.startIndex, this.endIndex);
},
// 處理滾動事件
handleScroll() {
this.updateVisibleData();
},
},
};
</script>
虛擬列表是解決海量數據渲染性能問題的利器,使用虛擬列表可以顯著提高列表的渲染效率和用戶體驗。在 Vue 項目中,我們可以借助虛擬列表組件或自行實現虛擬列表邏輯,優化列表性能,打造絲滑流暢的用戶體驗!
#頭條創作挑戰賽#
質文章,及時送達
作者:JasonGofen
鏈接:https://www.jianshu.com/p/95869ade37b3
本文內容主要講解Solr 7.7.1 環境搭建后使用Spring boot 2.1.3集成SolrJ實現簡易全文檢索微服務,對于Solr與Spring boot的介紹內容網上資料很多,本文不再贅述。
關于本文內容所涉及資源在最后會給大家統一都列出來。
Spring boot 結合 SolrJ 實現對Solr Server的訪問是非常簡單的,它們相互之間的關系如下圖所示。
主體實現是通過在Spring boot微服務中集成SolrJ,配置好Solr Server參數,調用SolrJ中的CRUD API實現請求Solr Server端進行添加、修改、刪除索引和查詢的操作。至于如何結合現有業務系統,我們后面介紹。
圖1 簡易環境說明
下面以最簡單快速的方式實現全文檢索基礎CRUD功能。
因自己的電腦硬盤空間滿了沒裝Linux虛擬機,就以Windows為例安裝Solr Server端了。其實總體而言兩個系統對Solr Server端的操作類似,各位看官舉一反三就好,就兩種系統部署Solr的不同下面也會做相應的提及。
已配置好的Solr 7.7.1下載:
https://pan.baidu.com/s/11s18oJVKpEVc-AmZO1xkgA
我們首先來了解一下Solr的常見命令:
啟動:
./solr start
關閉:
./solr stop -all
重啟:
./solr restart
創建Core:
./solr create -c YourCoreName -d _default
刪除Core:
./solr delete -c YourCoreName
關于Solr更細致的內容,大家可以參閱下方鏈接:
Solr 官網
https://lucene.apache.org/solr/
Solr API官方文檔
http://lucene.apache.org/solr/7_7_1/solr-solrj/index.html
Solr 中文文檔(譯版)
https://www.w3cschool.cn/solr_doc/solr_doc-t3642fkr.html
要想搭建Solr Server攏共分3步:
步驟1-1:下載安裝JDK和Solr Server端
下載安裝JDK 8:JDK的安裝在這就不說了,網上有很多資料。\
Java SE Development Kit 8 下載
下載Solr 7.7.1壓縮包:請注意Linux下載solr-7.7.1.tgz,Windows下載solr-7.7.1.zip\
http://archive.apache.org/dist/lucene/solr/
步驟1-2:解壓Solr-7.7.1壓縮包
Windows下解壓壓縮包到對應的目錄,我的路徑是:
C:\myworking\solr-7.7.1
Linux下使用 tar 命令解壓Solr壓縮包:
tar zxvf solr-7.7.1.tgz -C /myworking
步驟1-3:進入bin目錄運行Solr
Windows與Linux操作solr的命令都是一樣的,但都需要進入到Solr的bin
目錄下,我的目錄是C:\myworking\solr-7.7.1\bin
。linux的目錄使用cd
命令進入即可。
進入的到bin
目錄下執行啟動命令:
./solr start
啟動完成后的控制臺截圖:
圖2 控制臺Solr啟動完成圖
隨后我們訪問http://localhost:8983
即能看到Solr Server端的Web
頁面了
圖3 Solr Server端 Web首頁
步驟1-4:創建Core
Solr Core
的創建有兩種方式,第一種是通過命令行的方式,第二種是在SolrWeb
首頁中創建。
個人比較推薦第一種,原因有二,一是方便快捷在命令行一句話搞定,
Ctrl+c Ctrl+v
齊活兒,不用在頁面上點來點去還得敲文字,二是所在公司大牛在實踐過后說是如果采用的第二種方式創建出的Core
會有一些問題。本著聽人話,吃飽飯的態度就采用第一種吧~ ~*大家可以實踐一下然后分享給我哦。*當然兩種方式還是要介紹下的。
使用命令行創建Core
我們只需要進入到上述的bin
目錄,復制以下命令即可創建Core
,命令中的TestCore
為名稱可以自行替換:
./solr create -c TestCore -d _default
使用Web
端創建Core
上述圖3中左側的列表第3個Core Admin
菜單項,點開后就明白怎么做了。
在Web
端查看TestCore
圖4 選擇TestCore
圖5 TestCore詳情圖
介紹性的內容還是不羅列了,大家自己百度吧。Ik-Analyzer分詞據說是國內最好用的中文分詞,大部分人都用這個。目前Solr-7.7.1也自帶了一個中文分詞,具體的對比我沒做過,等裝完IK后大家回來可以進行下對比。同時歡迎分享給我哦。
IK分詞GitHub:
https://github.com/magese/ik-analyzer-solr7
動態詞庫自動加載:
https://github.com/liang68/ik-analyzer-solr6
http://www.cnblogs.com/liang1101/articles/6395016.html
PS:關于動態詞庫自動加載,這個大家看一下下面這段引用描述后視項目情況選擇要不要去研究下。
如果只是在我們原有的業務系統中簡單集成Solr,那暫時沒必要去了解動態詞庫自動加載。如果像商城等業務系統中,對于搜索模塊是業務系統的核心之一,那么簡單使用IK可能無法達到線上使用的要求。在IK分詞器中默認是一次啟動將主詞庫、停用詞以及擴展詞庫全部加載完畢,后續如果再想要增加額外的擴展詞,就必須得修改對應的擴展詞表重新打包上傳并重啟服務方能生效,這種方式不適合應用與線上服務。那么到底如何實現這種無縫擴充詞庫呢?大家可以看看上面的博客。
步驟2-1:配置IK-analyzer jar包和詞庫
首先需要大家下載jar包和源碼,我們下面需要放到Solr Server端對應的目錄下。
IK分詞jar包:
https://search.maven.org/remotecontent?filepath=com/github/magese/ik-analyzer/7.7.1/ik-analyzer-7.7.1.jar
IK分詞GitHub源碼:
https://github.com/magese/ik-analyzer-solr7
將下載好的ik-analyzer-7.7.1.jar
包放入Solr服務的webapp\WEB-INF\lib
目錄下,我的目錄全路徑是:
C:\myworking\solr-7.7.1\server\solr-webapp\webapp\WEB-INF\lib
將下載好的ik-analyzer-solr7-master
源碼下的src\main\resources
目錄中的文件***(如下)***,放入到webapp\WEB-INF\classes
目錄下:
① IKAnalyzer.cfg.xml 擴展配置文件
② ext.dic 擴展詞庫
③ stopword.dic 停止詞庫
④ ik.conf 動態詞庫配置文件
⑤ dynamicdic.txt 動態詞庫
我的目錄全路徑是:
C:\myworking\solr-7.7.1\server\solr-webapp\webapp\WEB-INF\classses
關于詞庫中同義詞庫、擴展詞庫、停止詞庫的介紹,可以看下面的blog:
https://blog.csdn.net/zcl_love_wx/article/details/52092894
步驟2-2. 配置TestCore
的server\solr\TestCore\conf\managed-schema
,添加IK分詞器,示例如下:
<!-- ik分詞器 -->
<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" conf="ik.conf"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
*PS:放在<schema name="default-config" version="1.6">
標簽下。*同時在該標簽下我們還需要配置field,請看步驟3。
Solr filed域的配置極為重要,filed的配置會影響到索引的創建和查詢出的結果展示。
<!-- Solr Test search -->
<field name="title" type="text_ik" indexed="true" stored="true" required="true" multiValued="true" />
<field name="content" type="text_ik" indexed="true" stored="true" required="true" multiValued="true" />
<field name="filetype" type="string" indexed="true" stored="true" required="true" multiValued="false" />
<field name="uploadtime" type="string" indexed="false" stored="true" required="true" multiValued="false" />
<!-- 復制域,可以將多個Field復制到一個Field中,以便進行統一的檢索,multiValued屬性需要設置成true -->
<copyField source="content" dest="title" />
name:查詢時的名稱
type:這個是之前定義的FieldType的名稱,在這使用的ik分詞
indexed:是否索引(true/false)
stored:是否存儲(是否將索引結果存儲到索引庫)
multivalued:是否多值(一般配合copyField使用)
動態filed
在定義
filed
時,可能會隨著業務主線作出變更,那么每次在managed-schema
更改filed
后,還需重啟Solr也是個麻煩事兒。那么在生產環境如此操作可能顯得不是那么理想了。那么可以在變更時使用類似通配符的方式建立動態filed
,比如name="title"
可以寫成name="fl_*"
,這樣只要以fl_
開頭的索引都可以被建立。
這里請注意Analyse Fieldname / FieldType:
右邊的下拉列表,需要去選中ik分詞text_ik
。我們可以看到輸入中華人民共和國
關鍵字后所出現的分詞效果。
圖6 分詞效果圖
至此我們的Solr Server端基礎版就搭建完成了,下面開始使用Spring boot結合SolrJ進行全文檢索微服務的搭建。
Spring boot的基礎知識不講解了,下面我們采用Spring boot 2.1.3結合SolrJ 7.7.1完成全文檢索微服務的實現。
下載源碼
https://github.com/JasonGofen/SolrProject
準備兩個doc文檔,寫入一些自定內容,放到指定目錄下,當然也不一定非得要doc。以下是我準備的兩個文件:
C:\solrfile\data\鵝鵝鵝.pdfC:\solrfile\data\靜夜思.docx
創建項目,在pom.xml
引入SolrJ
的Maven依賴
<!-- SolrJ 7.7.1 API -->
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>7.7.1</version>
</dependency>
<!-- 解析文檔內容工具包 -->
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>1.9</version>
</dependency>
目錄結構
├── src
│ └── main
│ ├── java
│ │ └── com.jasongofen
│ │ ├── client
│ │ │ └── SolrClient.java // Solr客戶端
│ │ ├── config
│ │ │ ├── CorsConfig.java // 跨域配置文件
│ │ │ └── SolrConfigProperties.java // yml屬性實例化配置文件
│ │ ├── test
│ │ │ └── SolrCURDTest.java // Solr API調用測試示例
│ │ ├── util
│ │ │ ├── ConvertUtil.java // 自定義轉換工具類
│ │ │ └── TikaUtil.java // 提取文檔內容工具類
│ │ └── SolrProjectApplication.java // Spring boot啟動類
│ └── resources
│ ├── application.yml // 項目配置
│ ├── banner.txt // banner配置
│ └── logback-spring.xml // 日志配置
├── pom.xml // 依賴配置
└── README.md // 項目幫助文檔
配置application.yml
中solr
節點下的屬性值***(必須)***
# solr配置
solr:
# Solr Server端地址
server: localhost:8983 # 設置你的Solr Server訪問地址
# Solr Core名稱
core: TestCore # 設置你的Solr Core名稱
# 上面準備的文檔的所在本地路徑
dir: C:\solrfile\data\ # 設置你的需要建立索引的文件所在目錄
下面就可以運行項目了,SolrJ API調用請看以下內容。未完待續
基礎的API調用代碼在項目目錄src\main\java\com.jasongofen.test\SolrCURDTest.java
文件中,該java
是一個Controller
可以以http
請求的方式模擬其他業務系統調用過程。
添加、修改索引
添加索引時首先使用HttpSolrClient
與Solr Server
建立連接,隨后解析需要建立索引的文件*(至于需要結合現有的業務系統是采用http ftp
等方式從各自的文件Server中獲取,還是另外的方式,請結合當前項目業務需要作擴展即可)*,接著把解析出的文件數據放到對應的索引位置,在設置索引內容時id
字段是必須要設置的且全局唯一,最后提交索引并關閉SolrClient
。
修改索引時,如果id
在索引庫中已存在,則執行更新操作。
@GetMapping("/Add")
public void solrAdd throws Exception {
// 設置文件路徑
List<String> files = new ArrayList<>;
files.add("鵝鵝鵝.pdf");
files.add("靜夜思.docx");
// 獲取Solr客戶端
HttpSolrClient solr = SolrClient.getClient(solrConfigProperties.getServer);
String prefix = "";
for (String fi : files) {
System.out.println(fi);
// 取后綴名
prefix = ConvertUtil.getFileSufix(fi);
if (prefix.equalsIgnoreCase("txt") ||
prefix.equalsIgnoreCase("docx") ||
prefix.equalsIgnoreCase("doc") ||
prefix.equalsIgnoreCase("pdf")) {
String fileInfo = fi.split("\.");
String content = "";
// 獲取文件流,取出文件內容
InputStream inputStream = new FileInputStream(solrConfigProperties.getDir + fi);
if (prefix.equals("txt")) {
content = TikaUtil.txt2String(inputStream);
} else if (prefix.equals("docx") || prefix.equals("doc") || prefix.equals("pdf")) {
content = TikaUtil.doc2String(inputStream);
} else {
inputStream.close;
}
// 添加索引
SolrInputDocument solrDoc = new SolrInputDocument;
String formatDate = ConvertUtil.formatDate;
// 執行添加 ps:如果id相同,則執行更新操作
solrDoc.addField("id", UUID.randomUUID.toString.toUpperCase.replace("-", ""));
solrDoc.addField("title", fileInfo[0]);
solrDoc.addField("content", content);
solrDoc.addField("filetype", prefix);
solrDoc.addField("uploadtime", formatDate);
solr.add(solrConfigProperties.getCore, solrDoc);
} else {
continue;
}
}
// 提交
solr.commit(solrConfigProperties.getCore);
solr.close;
}
查詢
查詢時因返回的是JSON串,并未做前端頁面展示,請根據業務需求自行定制。
@GetMapping("/Query")
public SolrDocumentList solrQuery throws Exception {
HttpSolrClient solrClient = SolrClient.getClient(solrConfigProperties.getServer);
// 定義查詢條件
Map<String, String> params = new HashMap<String, String>;
params.put("q", "*:*");
SolrParams mapSolrParams = new MapSolrParams(params);
//執行查詢 第一個參數是collection,就是我們在solr中創建的core
QueryResponse response = solrClient.query(solrConfigProperties.getCore, mapSolrParams);
// 獲取結果集
SolrDocumentList results = response.getResults;
for (SolrDocument result : results) {
// SolrDocument 數據結構為Map
System.out.println(result);
}
solrClient.close;
return results;
}
刪除索引
需要刪除索引時,根據id
去刪除即可。
@GetMapping("/Delete")
public void solrDelete(@RequestParam("id") String id) throws Exception {
HttpSolrClient solrClient = SolrClient.getClient(solrConfigProperties.getServer);
// 通過id刪除 執行要刪除的collection(core)
solrClient.deleteById(solrConfigProperties.getCore, id);
// 還可以通過查詢條件刪除
// solrClient.deleteByQuery(solrConfigProperties.getCore, "查詢條件");
// 提交刪除
solrClient.commit(solrConfigProperties.getCore);
solrClient.close;
}
本文所用資源匯總:
本文已配置的 Solr7.7.1https://pan.baidu.com/s/11s18oJVKpEVc-AmZO1xkgA
本文源碼https://github.com/JasonGofen/SolrProject
Solr 官網https://lucene.apache.org/solr/
Solr API 官方文檔http://lucene.apache.org/solr/7_7_1/solr-solrj/index.html
Solr 中文文檔(譯版)https://www.w3cschool.cn/solr_doc/solr_doc-t3642fkr.html
JDK 8Java SE Development Kit 8 下載
Solr 7.7.1 壓縮包http://archive.apache.org/dist/lucene/solr/
IK 分詞 jar 包https://search.maven.org/remotecontent?filepath=com/github/magese/ik-analyzer/7.7.1/ik-analyzer-7.7.1.jar
IK 分詞 GitHub 源碼https://github.com/magese/ik-analyzer-solr7
動態詞庫自動加載
https://github.com/liang68/ik-analyzer-solr6
http://www.cnblogs.com/liang1101/articles/6395016.html
同義詞典、擴展詞典、停止詞典介紹 Bloghttps://blog.csdn.net/zcl_love_wx/article/details/52092894
創建 Spring boot 項目的網址https://start.spring.io/
-END-
如果看到這里,說明你喜歡這篇文章,請轉發。同時標星(置頂)本公眾號可以第一時間接受到博文推送。1. 基友說:“自己整一個”HashMap為什么線程不安全?3.一致性Hash在負載均衡中的應用60個相見恨晚的神器工具
*請認真填寫需求信息,我們會在24小時內與您取得聯系。