Mongodb實(shí)戰(zhàn)之全文搜索功能
前言
眾所周知在傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)中,我們通常將數(shù)據(jù)結(jié)構(gòu)化,通過(guò)一系列表關(guān)聯(lián)、聚合來(lái)查詢我們所需的結(jié)果。而在非結(jié)構(gòu)化的數(shù)據(jù)中,缺少這種預(yù)定義的結(jié)構(gòu),因而如何快速查詢定位到我們所需要的結(jié)果,不是一件容易的事。
Mongodb作為一種NoSQL數(shù)據(jù)庫(kù),非常適合存儲(chǔ)和管理非結(jié)構(gòu)化數(shù)據(jù),例如互聯(lián)網(wǎng)上的各種文本數(shù)據(jù)。假如我們用Mongodb存儲(chǔ)了很多博客文章,那么如何快速找到所有關(guān)于“nodejs”這個(gè)主題的文章呢?Mongodb內(nèi)建的全文搜索可以幫助我們完成這個(gè)功能。下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹:
在本篇博文中,將要介紹的是我使用Mongdb text search的一些經(jīng)驗(yàn)。
Mongodb text search是什么?
Mongodb text search是Mongodb對(duì)數(shù)據(jù)庫(kù)進(jìn)行搜索的功能模塊,類似于數(shù)據(jù)庫(kù)內(nèi)建的搜索引擎。有些人可能會(huì)疑問(wèn),查數(shù)據(jù)庫(kù)為什么還需要搜索引擎?直接用條件查詢不就得了。例如在前面的文章主題搜索中,我們不可能事先提取出每篇文章的主題,然后用專門(mén)的字段存儲(chǔ),因此沒(méi)辦法進(jìn)行條件查詢。并且同一個(gè)主題詞,有多種不同的表達(dá)方式,例如”node”、”nodejs”可視為同一個(gè)主題。
Mongodb text search可以自動(dòng)地對(duì)大段的文本數(shù)據(jù)進(jìn)行分詞處理、模糊匹配、同義詞匹配,解決文本搜索的問(wèn)題。
建立文本索引
要使Mongodb能夠進(jìn)行全文搜索,首先要對(duì)搜索的字段建立文本索引。建立文本索引的關(guān)鍵字是text,我們既可以建立單個(gè)字段的文本索引,也可以建立包含多個(gè)字段的復(fù)合文本索引。需要注意的是,每個(gè)collection只能建立一個(gè)文本索引,且只能對(duì)String或String數(shù)組的字段建立文本索引。
我們可以通過(guò)以下命令,建立一個(gè)文本索引:
db.collection.createIndex({ subject: "text", content: "text" })
在mongoose中我們可以通過(guò)以下代碼,創(chuàng)建文本索引:
schema.index({ subject: "text", content: "text" })
需要注意的是:由于每個(gè)collection只支持一個(gè)文本索引,所以當(dāng)你需要在schema中添加或刪除文本索引字段時(shí),往往不起作用。這時(shí)候你需要到數(shù)據(jù)庫(kù)中,手動(dòng)刪除已經(jīng)建立的文本索引。
文本搜索示例
文本搜索的語(yǔ)法為:
{ $text: { $search: <string>, $language: <string>, $caseSensitive: <boolean>, $diacriticSensitive: <boolean> } }
在mongoose中,我們可以通過(guò)以下語(yǔ)句進(jìn)行文本搜索:
var query = model.find({ $text: { $search: "hello world" } })
$search后面的關(guān)鍵詞可以有多個(gè),關(guān)鍵詞之間的分隔符可以是多種字符,例如空格、下劃線、逗號(hào)、加號(hào)等,但不能是-和\",因?yàn)檫@兩個(gè)符號(hào)會(huì)有其他用途。搜索的多個(gè)關(guān)鍵字是or的關(guān)系,除非你的關(guān)鍵字包含-。例如hello world會(huì)包含所有匹配hello或world的文本,而hello -world只會(huì)匹配包含hello且不包含world的文本。
$language指示搜索的語(yǔ)言類型,在最新的Mongodb 3.2 enterprise版本中,已經(jīng)增加了對(duì)中文文本的搜索。
$caseSensitive設(shè)置是否區(qū)分大小寫(xiě)。
$diacriticSensitive設(shè)置是否區(qū)別發(fā)音符號(hào),CAFÉ于Café是同一語(yǔ)義,只是重音不一樣。
我們還可以對(duì)搜索的結(jié)果按匹配度進(jìn)行排序:
db.posts.find( { $text: { $search: "hello world" } }, { score: { $meta: "textScore" } } ).sort( { score: { $meta: "textScore" } } )
注意事項(xiàng)
Mongodb建立文本索引時(shí),會(huì)對(duì)提取所有文本的關(guān)鍵字建立索引,因而會(huì)造成一定的性能問(wèn)題。所以對(duì)于結(jié)構(gòu)化的字段,建議用普通的關(guān)系查詢,如果需要對(duì)大段的文本進(jìn)行搜索,才考慮用全文搜索。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持
相關(guān)文章
mongodb中隨機(jī)獲取1條記錄的實(shí)現(xiàn)方法
這篇文章運(yùn)用實(shí)例給大家演示了如何在mongodb中隨機(jī)獲取1條記錄,文中介紹的很詳細(xì),有需要的朋友們可以參考借鑒。下面來(lái)一起看看吧。2016-09-09PHP中MongoDB數(shù)據(jù)庫(kù)的連接、添加、修改、查詢、刪除等操作實(shí)例
這篇文章主要介紹了PHP中MongoDB數(shù)據(jù)庫(kù)的連接、添加、修改、查詢、刪除等操作實(shí)例,需要的朋友可以參考下2014-06-06聊聊MongoDB?帶訪問(wèn)控制的副本集部署問(wèn)題
這篇文章主要介紹了MongoDB?帶訪問(wèn)控制的副本集部署,本文給大家分享簡(jiǎn)單的步驟幫助大家完成,對(duì)MongoDB副本集部署問(wèn)題感興趣的朋友一起看看吧2022-02-02Mongodb如何使用killCursors停止運(yùn)行的cursor
MongoDB分批向用戶返回?cái)?shù)據(jù)結(jié)果,通過(guò)游標(biāo)的移動(dòng), mongodb確定當(dāng)前返回結(jié)果的位置,是否要加載更多數(shù)據(jù)到內(nèi)存當(dāng)中,這篇文章主要介紹了Mongodb如何使用killCursors停止運(yùn)行的cursor,需要的朋友可以參考下2023-12-12MongoDB特點(diǎn)與體系結(jié)構(gòu)等簡(jiǎn)介
今天小編就為大家分享一篇關(guān)于MongoDB特點(diǎn)與體系結(jié)構(gòu)等簡(jiǎn)介,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01mongodb 數(shù)據(jù)庫(kù)操作--備份 還原 導(dǎo)出 導(dǎo)入
mongodb數(shù)據(jù)備份和還原主要分為二種,一種是針對(duì)于庫(kù)的mongodump和mongorestore,一種是針對(duì)庫(kù)中表的mongoexport和mongoimport。2014-07-07MongoDB快速入門(mén)筆記(二)之MongoDB的概念及簡(jiǎn)單操作
MongoDB是面向集合的文檔式數(shù)據(jù)庫(kù),不像關(guān)系數(shù)據(jù)庫(kù)那樣,有表,列、行,mongoDB數(shù)據(jù)庫(kù)則是由一系列的文檔組成。接下來(lái)通過(guò)本文給大家介紹MongoDB的概念及簡(jiǎn)單操作,一起看看吧2016-06-06