天天看點

Neo4j 全文檢索

全文檢索基本概念

  • 搜尋

    搜尋這個行為是使用者與搜尋引擎的一次互動過程,使用者需要找一些資料,他提供給搜尋引擎一些限制條件.搜尋引擎通過限制條件抽取一些結果給使用者

  • 搜尋引擎

    搜尋引擎存在的目的是存儲,查找和擷取資料.Neo4j用的搜尋引擎是

    Lucene

  • 文檔

    在搜尋軟體中,文檔是一等公民.存儲,搜尋,顯示都是以文檔為核心.文檔簡單可以了解為資料庫中的一行資料,但是這行資料包括了field name.

  • 反向索引

    反向索引是搜尋引擎中核心資料結構.簡而言之,它将所有文檔變成像是一本書後面詞彙表的東西. 通過這種資料結構能夠快速的從一個單詞找到文檔

  • Lucene搜尋文法
Query implementation Purpose Example
TermQuery 單詞比對 neo4j
PhraseQuery 短語比對 "graph database"
RangeQuery 範圍比對 [A TO Z] {A TO Z}
WildcardQuery 正則比對 g*p?, d??abase
PrefixQuery 字首比對 algo*
FuzzyQuery 字尾比對 cipher~
BooleanQuery 查詢條件聚合 graph AND "shortest path"

環境準備

  • 容器啟動Neo4j

    docker run -p 17687:7687 -p 17474:7474 --name=neo4j-test neo4j:3.5.3

  • 建立資料, 使用測試資料.

    :play northwind-graph

Neo4j全文檢索

Neo4j全文檢索有以下特性,不過用下來最重要的我感覺是建立索引的語句實際上隻是建立于給命名控件. Neo4j從2.2.x時代開始就預設開啟

node_auto_indexing=true

. 反向索引在資料插入時候已經建立了. 建立索引/删除索引代價是非常小的

  • 支援關系與節點的索引
  • 支援常用

    analyzers

    擴充
  • 可以使用

    lucene query

    語句
  • 可以傳回查詢結果評分
  • 對索引自動更新
  • 單索引文檔數量不限

索引建立與删除

建立兩個索引, 一個是

Product

的該标簽的索引. 另外一個全資料庫全文檢索的索引

call db.index.fulltext.createNodeIndex("all",['Product', 'Category', 'Supplier'],['reorderLevel', 'unitsInStock', 'unitPrice', 'supplierID', 'productID', 'discontinued', 'quantityPerUnit', 'categoryID', 'unitsOnOrder', 'productName', 'description', 'categoryName', 'picture', 'country', 'address', 'contactTitle', 'city', 'phone', 'contactName', 'postalCode', 'companyName', 'fax', 'region', 'homePage'])
              call db.index.fulltext.createNodeIndex("product",['Product'],['reorderLevel', 'unitsInStock', 'unitPrice', 'supplierID', 'productID', 'quantityPerUnit', 'discontinued', 'productName', 'unitsOnOrder', 'categoryID'])           

删除索引

call db.index.fulltext.drop("all")           

可以通過函數擷取所有标簽和屬性

call db.propertyKeys
call db.labels           

查詢

這裡面的查詢非常簡單.隻要記住一個語句就能應付大多數場景

call db.index.fulltext.queryNodes(
    'all',        //這裡索引名
    'Av'          // lucene查詢語句
) yield node
where node.address contains "12"   // where語句
return node 
order by node.address  // order skip limit
skip 0
limit 1