成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Neo4j中實(shí)現(xiàn)自定義中文全文索引

張率功 / 2058人閱讀

摘要:默認(rèn)采用實(shí)現(xiàn)可定制,如自定義實(shí)現(xiàn)的索引,但默認(rèn)新建的索引只支持精確匹配,模糊查詢的話需要以全文索引,控制后臺(tái)的分詞行為。本文以常用的分詞器為例,介紹如何在中對字段新建全文索引實(shí)現(xiàn)模糊查詢。

數(shù)據(jù)庫檢索效率時(shí),一般首要優(yōu)化途徑是從索引入手,然后根據(jù)需求再考慮更復(fù)雜的負(fù)載均衡、讀寫分離和分布式水平/垂直分庫/表等手段;索引通過信息冗余來提高檢索效率,其以空間換時(shí)間并會(huì)降低數(shù)據(jù)寫入的效率,因此對索引字段的選擇非常重要。

Neo4j可對指定Label的Node Create Index,當(dāng)新增/更新符合條件的Node屬性時(shí),Index會(huì)自動(dòng)更新。Neo4j Index默認(rèn)采用Lucene實(shí)現(xiàn)(可定制,如Spatial Index自定義實(shí)現(xiàn)的RTree索引),但默認(rèn)新建的索引只支持精確匹配(get),模糊查詢(query)的話需要以全文索引,控制Lucene后臺(tái)的分詞行為。

Neo4j全文索引默認(rèn)的分詞器是針對西方語種的,如默認(rèn)的exact查詢采用的是lucene KeywordAnalyzer(關(guān)鍵詞分詞器),fulltext查詢采用的是 white-space tokenizer(空格分詞器),大小寫什么的對中文沒啥意義;所以針對中文分詞需要掛一個(gè)中文分詞器,如IK Analyzer,Ansj,至于類似梁廠長家的基于深度學(xué)習(xí)的分詞系統(tǒng)pullword,那就更厲害啦。

本文以常用的IK Analyzer分詞器為例,介紹如何在Neo4j中對字段新建全文索引實(shí)現(xiàn)模糊查詢。

IKAnalyzer分詞器

IKAnalyzer是一個(gè)開源的,基于java語言開發(fā)的輕量級的中文分詞工具包。

IKAnalyzer3.0特性

采用了特有的“正向迭代最細(xì)粒度切分算法“,支持細(xì)粒度和最大詞長兩種切分模式;具有83萬字/秒(1600KB/S)的高速處理能力。

采用了多子處理器分析模式,支持:英文字母、數(shù)字、中文詞匯等分詞處理,兼容韓文、日文字符優(yōu)化的詞典存儲(chǔ),更小的內(nèi)存占用。支持用戶詞典擴(kuò)展定義

針對Lucene全文檢索優(yōu)化的查詢分析器IKQueryParser(作者吐血推薦);引入簡單搜索表達(dá)式,采用歧義分析算法優(yōu)化查詢關(guān)鍵字的搜索排列組合,能極大的提高Lucene檢索的命中率。
IK Analyser目前還沒有maven庫,還得自己手動(dòng)下載install到本地庫,下次空了自己在github做一個(gè)maven私有庫,上傳這些maven central庫里面沒有的工具包。

IKAnalyzer自定義用戶詞典 詞典文件

自定義詞典后綴名為.dic的詞典文件,必須使用無BOM的UTF-8編碼保存的文件。

詞典配置

詞典和IKAnalyzer.cfg.xml配置文件的路徑問題,IKAnalyzer.cfg.xml必須在src根目錄下。詞典可以任意放,但是在IKAnalyzer.cfg.xml里要配置對。如下這種配置,ext.dic和stopword.dic應(yīng)當(dāng)在同一目錄下。



  
IK Analyzer 擴(kuò)展配置


/ext.dic;


/stopword.dic
Neo4j全文索引構(gòu)建

指定IKAnalyzer作為luncene分詞的analyzer,并對所有Node的指定屬性新建全文索引

  @Override
  public void createAddressNodeFullTextIndex () {
      try (Transaction tx = graphDBService.beginTx()) {
        IndexManager index = graphDBService.index();
        Index addressNodeFullTextIndex =
              index.forNodes( "addressNodeFullTextIndex", MapUtil.stringMap(IndexManager.PROVIDER, "lucene", "analyzer", IKAnalyzer.class.getName()));

        ResourceIterator 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全文索引測試

對關(guān)鍵詞(如"有限公司"),多關(guān)鍵詞模糊查詢(如"蘇州 教育 公司")默認(rèn)都能檢索,且檢索結(jié)果按關(guān)聯(lián)度已排好序。

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 addressNodeFullTextIndex = index.forNodes("addressNodeFullTextIndex" ,
                              MapUtil. stringMap(IndexManager.PROVIDER, "lucene", "analyzer" , IKAnalyzer.class.getName()));
                  IndexHits foundNodes = addressNodeFullTextIndex.query("text" , "蘇州 教育 公司" );
                   for (Node node : foundNodes) {
                        AddressNode entity = JsonUtil.ConvertMap2POJO(node.getAllProperties(), AddressNode. class, false, true);
                        System. out.println(entity.getAll地址實(shí)全稱());
                  }
                  tx.success();
            }
      }
}
CyperQL中使用自定義全文索引查詢 正則查詢
profile  
match (a:AddressNode{ruleabbr:"TOW",text:"唯亭鎮(zhèn)"})<-[r:BELONGTO]-(b:AddressNode{ruleabbr:"STR"})
where b.text=~ "金陵.*"
return a,b
全文索引查詢
profile
START b=node:addressNodeFullTextIndex("text:金陵*")
match (a:AddressNode{ruleabbr:"TOW",text:"唯亭鎮(zhèn)"})<-[r:BELONGTO]-(b:AddressNode)
where b.ruleabbr="STR"
return a,b
LegacyIndex中建立聯(lián)合exact和fulltext索引

對label為AddressNode的節(jié)點(diǎn),根據(jù)節(jié)點(diǎn)屬性ruleabbr的分類addressnode_fulltext_index(省->市->區(qū)縣->鄉(xiāng)鎮(zhèn)街道->街路巷/物業(yè)小區(qū))/addressnode_exact_index(門牌號(hào)->樓幢號(hào)->單元號(hào)->層號(hào)->戶室號(hào)),對屬性text分別建不同類型的索引

profile
START a=node:addressnode_fulltext_index("text:商業(yè)街"),b=node:addressnode_exact_index("text:二期19")
match (a:AddressNode{ruleabbr:"STR"})-[r:BELONGTO]-(b:AddressNode{ruleabbr:"TAB"})
return a,b limit 10

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/17533.html

相關(guān)文章

  • 如何在Canvas中實(shí)現(xiàn)自定義路徑動(dòng)畫

    摘要:在最近的項(xiàng)目中筆者需要做一個(gè)新需求在中實(shí)現(xiàn)自定義的路徑動(dòng)畫。當(dāng)我們決定要在制作自定義路徑動(dòng)畫時(shí),我們不僅要考慮如何實(shí)現(xiàn),更要考慮性能優(yōu)化,比如在這個(gè)實(shí)現(xiàn)思路中,我們是否可以減少不必要的渲染次數(shù)幀率如何控制達(dá)到最優(yōu)等等。 在最近的項(xiàng)目中筆者需要做一個(gè)新需求:在canvas中實(shí)現(xiàn)自定義的路徑動(dòng)畫。這里所謂的自定義路徑不單單包括一條直線,也許是多條直線的運(yùn)動(dòng)組合,甚至還包含了貝塞爾曲線,因此...

    Cympros 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<