Neo4j中實現自定義中文全文索引
資料庫檢索效率時,一般首要優化途徑是從索引入手,然後根據需求再考慮更復雜的負載均衡、讀寫分離和分散式水平/垂直分庫/表等手段;索引通過資訊冗餘來提高檢索效率,其以空間換時間並會降低資料寫入的效率,因此對索引欄位的選擇非常重要。
Neo4j可對指定Label的Node Create Index,當新增/更新符合條件的Node屬性時,Index會自動更新。Neo4j Index預設採用Lucene實現(可定製,如Spatial Index自定義實現的RTree索引),但預設新建的索引只支援精確匹配(get),模糊查詢(query)的話需要以全文索引,控制Lucene後臺的分詞行為。
Neo4j全文索引預設的分詞器是針對西方語種的,如預設的exact查詢採用的是lucene KeywordAnalyzer(關鍵詞分詞器),fulltext查詢採用的是 white-space tokenizer(空格分詞器),大小寫什麼的對中文沒啥意義;所以針對中文分詞需要掛一箇中文分詞器,如IK Analyzer,Ansj,至於類似樑廠長家的基於深度學習的分詞系統pullword,那就更厲害啦。
本文以常用的IK Analyzer分詞器為例,介紹如何在Neo4j中對欄位新建全文索引實現模糊查詢。
IKAnalyzer分詞器
IKAnalyzer是一個開源的,基於java語言開發的輕量級的中文分詞工具包。
IKAnalyzer3.0特性
採用了特有的“正向迭代最細粒度切分演算法“,支援細粒度和最大詞長兩種切分模式;具有83萬字/秒(1600KB/S)的高速處理能力。
採用了多子處理器分析模式,支援:英文字母、數字、中文詞彙等分詞處理,相容韓文、日文字元優化的詞典儲存,更小的記憶體佔用。支援使用者詞典擴充套件定義
針對Lucene全文檢索優化的查詢分析器IKQueryParser(作者吐血推薦);引入簡單搜尋表示式,採用歧義分析演算法優化查詢關鍵字的搜尋排列組合,能極大的提高Lucene檢索的命中率。
IK Analyser目前還沒有maven庫,還得自己手動下載install到本地庫,下次空了自己在github做一個maven私有庫,上傳這些maven central庫裡面沒有的工具包。
IKAnalyzer自定義使用者詞典
詞典檔案
自定義詞典字尾名為.dic的詞典檔案,必須使用無BOM的UTF-8編碼儲存的檔案。
詞典配置
詞典和IKAnalyzer.cfg.xml配置檔案的路徑問題,IKAnalyzer.cfg.xml必須在src根目錄下。詞典可以任意放,但是在IKAnalyzer.cfg.xml裡要配置對。如下這種配置,ext.dic和stopword.dic應當在同一目錄下。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 擴充套件配置</comment>
<!--使用者可以在這裡配置自己的擴充套件字典 -->
<entry key="ext_dict">/ext.dic;</entry>
<!--使用者可以在這裡配置自己的擴充套件停止詞字典-->
<entry key="ext_stopwords">/stopword.dic</entry>
</properties>
Neo4j全文索引構建
指定IKAnalyzer作為luncene分詞的analyzer,並對所有Node的指定屬性新建全文索引
@Override
public void createAddressNodeFullTextIndex () {
try (Transaction tx = graphDBService.beginTx()) {
IndexManager index = graphDBService.index();
Index<Node> addressNodeFullTextIndex =
index.forNodes( "addressNodeFullTextIndex", MapUtil.stringMap(IndexManager.PROVIDER, "lucene", "analyzer", IKAnalyzer.class.getName()));
ResourceIterator<Node> nodes = graphDBService.findNodes(DynamicLabel.label( "AddressNode"));
while (nodes.hasNext()) {
Node node = nodes.next();
//對text欄位新建全文索引
Object text = node.getProperty( "text", null);
addressNodeFullTextIndex.add(node, "text", text);
}
tx.success();
}
}
Neo4j全文索引測試
對關鍵詞(如’有限公司’),多關鍵詞模糊查詢(如’蘇州 教育 公司’)預設都能檢索,且檢索結果按關聯度已排好序。
package uadb.tr.neodao.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.index.Index;
import org.neo4j.graphdb.index.IndexHits;
import org.neo4j.graphdb.index.IndexManager;
import org.neo4j.helpers.collection.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.wltea.analyzer.lucene.IKAnalyzer;
import com.lt.uadb.tr.entity.adtree.AddressNode;
import com.lt.util.serialize.JsonUtil;
/**
* AddressNodeNeoDaoTest
*
* @author geosmart
*/
@RunWith(SpringJUnit4ClassRunner. class)
@ContextConfiguration(locations = { "classpath:app.neo4j.cfg.xml" })
public class AddressNodeNeoDaoTest {
@Autowired
GraphDatabaseService graphDBService;
@Test
public void test_selectAddressNodeByFullTextIndex() {
try (Transaction tx = graphDBService.beginTx()) {
IndexManager index = graphDBService.index();
Index<Node> addressNodeFullTextIndex = index.forNodes("addressNodeFullTextIndex" ,
MapUtil. stringMap(IndexManager.PROVIDER, "lucene", "analyzer" , IKAnalyzer.class.getName()));
IndexHits<Node> foundNodes = addressNodeFullTextIndex.query("text" , "蘇州 教育 公司" );
for (Node node : foundNodes) {
AddressNode entity = JsonUtil.ConvertMap2POJO(node.getAllProperties(), AddressNode. class, false, true);
System. out.println(entity.getAll地址實全稱());
}
tx.success();
}
}
}
CyperQL中使用自定義全文索引查詢
正則查詢
profile
match (a:AddressNode{ruleabbr:'TOW',text:'唯亭鎮'})<-[r:BELONGTO]-(b:AddressNode{ruleabbr:'STR'})
where b.text=~ '金陵.*'
return a,b
全文索引查詢
profile
START b=node:addressNodeFullTextIndex("text:金陵*")
match (a:AddressNode{ruleabbr:'TOW',text:'唯亭鎮'})<-[r:BELONGTO]-(b:AddressNode)
where b.ruleabbr='STR'
return a,b
LegacyIndex中建立聯合exact和fulltext索引
對label為AddressNode的節點,根據節點屬性ruleabbr的分類addressnode_fulltext_index(省->市->區縣->鄉鎮街道->街路巷/物業小區)/addressnode_exact_index(門牌號->樓幢號->單元號->層號->戶室號),對屬性text分別建不同型別的索引
profile
START a=node:addressnode_fulltext_index("text:商業街"),b=node:addressnode_exact_index("text:二期19")
match (a:AddressNode{ruleabbr:'STR'})-[r:BELONGTO]-(b:AddressNode{ruleabbr:'TAB'})
return a,b limit 10
相關文章
原文地址:https://codertw.com/%e8%b3%87%e6%96%99%e5%ba%ab/10006/
Neo4j中實現自定義中文全文索引的更多相关文章
- Q郵箱轉移自定義目錄中的郵件
1.之前在Q郵箱上建立了許多規則和收件箱,現在想統一用Mac上的郵局管理 2.Mac上會同步對應郵箱的自定義目錄,此時這些目錄便十分多餘礙眼 3.Q郵箱單頁顯示郵件數量上限是100,這意味著手動轉移十 ...
- 可以支持jQuery1.10.1 的 fancybox 1.3.4, 並現在type為Ajax時,也可以定義窗口的大小。
官網上的 fancybox 1.3.4 太老了,不支持jQuery1.10.1,改動了一下源碼,現在可以支持了. type為Ajax時,也可以定義窗口的大小. $("#ajaxlink&qu ...
- 在Android中afinal框架下實現sqlite數據庫版本升級的辦法
public abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int new Version) 這個方法在實現時需要重寫. pub ...
- Neo4j中实现自定义中文全文索引
数据库检索效率时,一般首要优化途径是从索引入手,然后根据需求再考虑更复杂的负载均衡.读写分离和分布式水平/垂直分库/表等手段:索引通过信息冗余来提高检索效率,其以空间换时间并会降低数据写入的效率:因此 ...
- [實現DDD] 第10章 聚合(1)設計原則
聚合只是將一些實體(Entity)與值對象(Value Object)聚集起來的對象樹嗎?? 有些途徑可能使我們設計出不正確的聚合模型, 如:可能為了對象組合上的方便而將聚合設計的很大;也可能設計的聚 ...
- dataTable.NET的column index的不同定義
dataTable.NET是一個jQuery的plug in 第三方的library, 用來實現web page中table的interaction controls, 另外最近有在用的還有Teler ...
- Linux Ubuntu 虛擬機系統自定義桌面分辨率且重啓後保持不變
我用 VMware Workstation 12 Pro 安裝的 Ubuntu MATE Desktop Environment 1.12.1,發現安裝後沒有需要的分辨率,於是安裝 VMware To ...
- 使用Mutex實現單一程式執行個體的注意事項(转)
相信大家都知道在.NET程式中若要實現單一程式執行個體,一般來說有幾種方法,像是去判斷是否已經有開啟的Process是相同的程式.用Mutex與Semaphore之類的技術來判斷是否程式正在開啟.但是 ...
- #HTML:無序、有序與定義清單
#HTML:無序.有序與定義清單 Maplewing 于 星期六, 12/10/2013 - 09:48 提交 清單在網頁中是很常使用到的東西,故多少還是要了解一下.在HTML中有三種不太一樣的清單, ...
随机推荐
- 火狐RESTClient和HttpRequester, Chrome的Postman使用详解
Chrome下有著名的Postman,那火狐也有它的左膀右臂,那就是RESTClient和HttpRequester.这两款工具都是火狐的插件,主要用来模拟发送HTTP请求,HTTP请求最常用的两种方 ...
- jmeter 创建接口测试案例
1 怎么做接口测试? 一般情况下,由于我们项目前后调用主要是基于http协议的接口,所以测试接口时主要是通过工具或代码模拟http请求的发送和接收.所以我们下面整理了一下使用Jmeter工具进行htt ...
- 20、Linux命令对服务器磁盘进行监控
服务器磁盘性能测试也是一个比较有意思的过程.首先我们要弄清楚磁盘储存哪些内容,这里推荐鸟哥的私房菜 我们不仅要推算出磁盘什么时候被占满,也要监控磁盘的读写速度.也就是我们常说的 I/O df -h ...
- 2014 mathtype分块列向量输入 PPT动画制作
1.mathtype分块列向量的输入 http://zhidao.baidu.com/link?url=pV7TazWe-Ld5qgxNcJCQdRaA8ILEgmXRP211F5U0Cst0xNfU ...
- Apriori-关联规则挖掘算法
Apriori算法采用的是自底向上的方法,从1-频繁集开始,逐步找出高阶频繁集. 它的基本流程是:第一次扫描交易数据库D时,产生1- 频繁集.在此基础上经过连接.修剪产生2-频繁集.以此类推,直到无法 ...
- 6-vim-移动命令-01-方向和行内移动
移动 命令模式下快速移动光标 编辑操作命令与移动命令结合使用 1.上下左右 命令 功能 手指 h 向左 食指 j 向下 食指 k 向上 中指 l 向右 无名指 2.行内移动 命令 英文 功能 w wo ...
- Swift结构体和类
Swift结构体 在Swift标准中,绝大多数的公开的类型都是结构体,而枚举和类只占很小的一部分 比如Bool.Int.Double.String.Array.Dictionary等常见的类型都是结构 ...
- Pregel 消息传递机制
- 安装Storm的基本过程
- linux redis的启动---后台启动
1.启动redis服务: redis-server 如果想要开启后台进程: 1.找到redis.conf里边的 把no 改为yes. 2.redis-server redis.conf(这个是针对两个 ...