mongo索引(特別是文本索引)

前言

首先,我想說的是,看官方文檔很重要,雖然可能都是英文,并且也很長(zhǎng),但是基本都很有用。

普通索引

不多介紹,一搜一大把,簡(jiǎn)要介紹可以看菜鳥教程

文本索引

之前在進(jìn)行文本匹配時(shí)候,用的是正則$regex,后來發(fā)現(xiàn)mongo自帶有一個(gè)文本索引,所以就研究了下

首先上官方文檔,這里有一個(gè)中文版本的,但是中文版本缺少內(nèi)容。可以先看中文版,然后補(bǔ)充看英文版

簡(jiǎn)要說明一下重點(diǎn)(用了中文版本中的例子)

建立索引

db.stores.createIndex( { name: "text", description: "text" } )

find操作

db.stores.find( { $text: { $search: "java coffee shop" } } )

注意,上面匹配到的是只要包含java coffee shop中至少一個(gè)詞就返回結(jié)果,否則用精確搜索

精確索引(這一點(diǎn)在后面會(huì)補(bǔ)充)

db.stores.find( { $text: { $search: "java \"coffee shop\"" } } )

詞語排除

db.stores.find( { $text: { $search: "java shop -coffee" } } )

排序

db.stores.find(
   { $text: { $search: "java coffee shop" } },
   { score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" } } )

根據(jù)英文版本補(bǔ)充

首先,在find時(shí)候有額外的幾個(gè)參數(shù)可選,

{
  $text:
    {
      $search: <string>,
      $language: <string>,
      $caseSensitive: <boolean>,
      $diacriticSensitive: <boolean>
    }
}

大小寫敏感$caseSensitive,默認(rèn)是false
發(fā)音敏感$diacriticSensitive,默認(rèn)是false。這個(gè)要說明一下,搜索發(fā)現(xiàn)具體解釋可以看此處,簡(jiǎn)單說就是,如果不敏感,那么As such, the index also does not distinguish between é, é, e, and E.

限制

挑幾個(gè)說,具體還是看英文文檔去

  • A query can specify, at most, one $text expression.
    這一點(diǎn)的話,我當(dāng)時(shí)想搜索同時(shí)匹配兩個(gè)詞的情況,在Robo 3Tfind里面用多個(gè)沒問題,但是后來在程序里面pymongo就遇到了問題,但是后來發(fā)現(xiàn)沒有必要,下文會(huì)解釋

如果用在aggregation里面

  • The $match stage that includes a $text must be the first stage in the pipeline.
  • A text operator can only occur once in the stage.
  • The text search, by default, does not return the matching documents in order of matching scores. Use the $meta aggregation expression in the $sort stage.

否定詞

  • A hyphenated word, such as pre-market, is not a negation. If used in a hyphenated word, $textoperator treats the hyphen-minus (-) as a delimiter. To negate the word market in this instance, include a space between pre and -market, i.e., pre -market.

連字符詞,如pre-market,不是否定詞。如果在帶連字符的單詞中使用,$text操作符將連字符-(-)作為分隔符。要在本例中否定market一詞,請(qǐng)?jiān)?code>pre和-market之間加上空格,即pre -market。

關(guān)于這一點(diǎn),我也有一點(diǎn)想補(bǔ)充說
在最后使用時(shí)發(fā)現(xiàn),當(dāng)搜索hand時(shí)候,如果文本中有hand-helds也會(huì)被搜索到,但是handhelds不會(huì),那是不是和這個(gè)-相關(guān)呢?待考證
所以在使用時(shí)需要注意上面這個(gè)細(xì)節(jié)

另外

Stop Words

  • 會(huì)自動(dòng)去掉Stop Words
    The $text operator ignores language-specific stop words, such as the and and in English.

Stemmed Words

  • 詞根 (居然能自動(dòng)實(shí)現(xiàn))
    For case insensitive and diacritic insensitive(前提) text searches, the $text operator matches on the complete stemmed word. So if a document field contains the word blueberry, a search on the term blue will not match. However, blueberry or blueberries will match.

注意:mongo會(huì)自動(dòng)將text的內(nèi)容以及find中的query都進(jìn)行stemmed處理

補(bǔ)充精確搜索(同時(shí)包含多個(gè)詞)

上面說到,當(dāng)時(shí)我想搜索同時(shí)包含兩個(gè)詞(eg:java coffee shop)的文檔,如果用db.stores.find( { $text: { $search: "java coffee shop" } } )得到的是至少包含一個(gè)詞的結(jié)果
所以一開始我想用db.stores.find( { $text: { $search: "java" }, $text: { $search: "coffee" } } )這樣
在robo上可行,但是在pymongo里面不可行(上面文檔也說不行)
后來發(fā)現(xiàn)直接db.stores.find( { $text: { $search: "\"java\" \"coffee\" \"shop\"" } } )這樣就夠了,反斜杠只是為了區(qū)分引號(hào)
而在python里面可以通過單雙引號(hào)來實(shí)現(xiàn)

que_str = ''
for que in filtered_query: #對(duì)于text索引的多條件
    que_str += '"' + que + '"'
con.append({'$text':{'$search':que_str}})

補(bǔ)充參考

https://docs.mongodb.com/manual/core/index-text/ 這個(gè)好像是index-text的介紹

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 晚上與哥哥對(duì)壘象棋。 久未摸棋,棋技生疏的厲害,第一局很快便落敗。 哥哥卻顯得很輕松,隨手吃起了酒鬼花生。 第二局...
    凡戊閱讀 287評(píng)論 0 0
  • 今天休班,全天帶娃。 途途上完樂高后不想回家,我想應(yīng)該是沒玩夠,想著正好也休息,直接帶孩子去新瑪特吃鐵板...
    段小可閱讀 284評(píng)論 0 0

友情鏈接更多精彩內(nèi)容