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应当在同一目录下。
1234567891011<?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的指定属性新建全文索引
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[@Override](/user/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全文索引测试
对关键词(如’有限公司’),多关键词模糊查询(如’苏州 教育 公司’)默认都能检索,且检索结果按关联度已排好序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
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](/user/author) geosmart
*/
@RunWith(SpringJUnit4ClassRunner. class)
@ContextConfiguration(locations = { "classpath:app.neo4j.cfg.xml" })
public class AddressNodeNeoDaoTest {
[@Autowired](/user/Autowired)
GraphDatabaseService graphDBService;
[@Test](/user/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中使用自定义全文索引查询
正则查询
1
2
3
4
|
profile
match (a:AddressNode{ruleabbr:'TOW',text:'唯亭镇'})<-[r:BELONGTO]-(b:AddressNode{ruleabbr:'STR'})
where b.text=~ '金陵.*'
return a,b
|
全文索引查询
1
2
3
4
5
|
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分别建不同类型的索引
1
2
3
4
|
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
|
原文地址:http://neo4j.com.cn/topic/58184ea2cdf6c5bf145675c3
Neo4j中实现自定义中文全文索引的更多相关文章
- Neo4j中實現自定義中文全文索引
資料庫檢索效率時,一般首要優化途徑是從索引入手,然後根據需求再考慮更復雜的負載均衡.讀寫分離和分散式水平/垂直分庫/表等手段:索引通過資訊冗餘來提高檢索效率,其以空間換時間並會降低資料寫入的效率,因此 ...
- solr服务中集成IKAnalyzer中文分词器、集成dataimportHandler插件
昨天已经在Tomcat容器中成功的部署了solr全文检索引擎系统的服务:今天来分享一下solr服务在海量数据的网站中是如何实现数据的检索. 在solr服务中集成IKAnalyzer中文分词器的步骤: ...
- MySQL中文全文索引插件 mysqlcft 1.0.0 安装使用文档[原创]
[文章+程序 作者:张宴 本文版本:v1.0 最后修改:2008.07.01 转载请注明原文链接:http://blog.zyan.cc/post/356/] MySQL在高并发连接.数据库记录数较多 ...
- 安装完Linux Mint后,发现系统中竟没有中文输入法
安装完Linux Mint后,发现系统中竟没有中文输入法,语言支持之后自动更新过程中有些安装包下载失败. 可以采取下面的方法安装上中文输入法. 1. 安装iBus: sudo add-apt-repo ...
- UWP中实现自定义标题栏
UWP中实现自定义标题栏 0x00 起因 在UWP开发中,有时候我们希望实现自定义标题栏,例如在标题栏中加入搜索框.按钮之类的控件.搜了下资料居然在一个日文网站找到了一篇介绍这个主题的文章: http ...
- Entity Framework 6 Recipes 2nd Edition(10-5)译 -> 在存储模型中使用自定义函数
10-5. 在存储模型中使用自定义函数 问题 想在模型中使用自定义函数,而不是存储过程. 解决方案 假设我们数据库里有成员(members)和他们已经发送的信息(messages) 关系数据表,如Fi ...
- Android XML中引用自定义内部类view的四个why
今天碰到了在XML中应用以内部类形式定义的自定义view,结果遇到了一些坑.虽然通过看了一些前辈写的文章解决了这个问题,但是我看到的几篇都没有完整说清楚why,于是决定做这个总结. 使用自定义内部类v ...
- ASP.NET Core中显示自定义错误页面-增强版
之前的博文 ASP.NET Core中显示自定义错误页面 中的方法是在项目中硬编码实现的,当有多个项目时,就会造成不同项目之间的重复代码,不可取. 在这篇博文中改用middleware实现,并且放在独 ...
- Web(Jsp+ Servlet)开发中如何解决中文乱码问题
1.中文乱码的成因 编码的字符集和解码的字符集不一致. 2.web开发过程中可能出现的乱码的位置及解决方案 ①request乱码 在向服务器传递数据时,所传递的中文有可能出现乱码. post请求(协议 ...
随机推荐
- 24、echarts做报表
1.今天就来讲一讲echarts的使用 使用步骤 (1)首先需要下载包echarts.js,然后引入该包, <!DOCTYPE html> <html> <header& ...
- Idea 导入项目不能运行
1.项目结构里面配置sdk,配置output输出目录 2.配置语言等级 配置src源文件目录 配置目录里面添加application,添加main class
- 【开发者笔记】Linq 多表关联排序操作
c# 一直是一门好用的语言,但是像linq这种骚操作实在是记不住.特此记下以备后用. var ls = from c in db.T_ProductReturnEntity join s in db. ...
- Python CookBook(self report)
Python CookBook 中文版:https://python3-cookbook.readthedocs.io/zh_CN/latest/copyright.html 英文版:https:// ...
- Selenium3 + Python3自动化测试系列七——多窗口切换
多窗口切换 在页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要主机切换到新打开的窗口上进行操作. WebDriver提供了switch_to.window()方法,可以实现在不同的窗口之间切 ...
- Vue+element ui table 导出到excel
需求: Vue+element UI table下的根据搜索条件导出当前所有数据 参考: https://blog.csdn.net/u010427666/article/details/792081 ...
- centos6.8 oracle 11.2.0.4 11g安装
配置Linux系统参数 配置阿里云yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup ...
- linux 下安装mysql5.7.17
安装前的环境准备 linux 环境准备 内核参数建议值 1.调整最大文件数限制 直接执行 ulimit -n 65535 或写入/etc/sysctl.conf 重启后生效 2.修改IO 调度器设置 ...
- rest framework之APIView
一.rest framework配置 1.安装rest framework 在django环境中安装rest-framework框架: (automatic) C:\Users\Administrat ...
- echarts点击柱状图时触发点击事件
项目需求:1.通过echarts把数据展示为柱状图2.点击对应的柱状图 显示对应的弹窗 主要用到的时 echarts中的 "click" 事件, 使用demo: var myCha ...