MongoDB全文检索

1年前 (2024-04-27)
从 2.4 版本开始,MongoDB 开始支持全文检索功能,全文检索就是对文本中的每个词建立索引,指明该词在文章现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户,整个过程类似于通过字典中的检索字表查字的过程。

目前,MongoDB 支持大约 15 种语言的全文索引,例如 danish、dutch、english、finnish、french、german、hungarian、italian、norwegian、portuguese、romanian、russian、spanish、swedish、turkish 等。

启用全文检索

最初,全文检索是一个实验性功能,但 MongoDB 在 2.6 版本以后默认开启了此功能,如果您使用 2.6 之前的版本,则需要使用以下代码来启用全文检索:

>db.adminCommand({setParameter:true, textSearchEnabled:true})

或者使用令:

mongod --setParameter textSearchEnabled=true

创建全文索引

假如我们在 posts 中插入以下文档:

> db.posts.insert([

... {

... "post_text": "enjoy the mongodb articles on bianchengbang",

... "tags": ["mongodb", "bianchengbang"]

... },

... {

... "post_text" : "writing tutorials on mongodb",

... "tags" : [ "mongodb", "tutorial" ]

... }

... ])

BulkWriteResult({

"writeErrors" : [ ],

"writeConcernErrors" : [ ],

"nInserted" : 2,

"nUpserted" : 0,

"nMatched" : 0,

"nModified" : 0,

"nRemoved" : 0,

"upserted" : [ ]

})

若要在 post_text 字段上创建全文索引,以便我们可以直接搜索字段中的内容,可以像下面这样:

> db.posts.createIndex({post_text:"text"})

{

"createdCollectionAutomatically" : false,

"numIndexesBefore" : 1,

"numIndexesAfter" : 2,

"ok" : 1

}

使用全文索引

使用全文索引可以提高搜索效率,前面我们已经在 post_text 字段上创建了全文索引,下面通过一个示例来演示全文索引的使用。

【示例】搜索 post_text 字段中包含关键词“bianchengbang”的所有文档:

> db.posts.find({$text:{$search:"bianchengbang"}}).pretty()

{

"_id" : ObjectId("6041dfc3835e4aa734b591df"),

"post_text" : "enjoy the mongodb articles on bianchengbang",

"tags" : [

"mongodb",

"bianchengbang"

]

}

如果您使用的是旧版本的 MongoDB,则可以使用以下令:

>db.posts.runCommand("text",{search:"bianchengbang"})

删除全文索引

要删除现有的全文索引,首先我们需要使用 getIndex() 方法来查看索引的名称,如下所示:

> db.posts.getIndexes()

[

{

"v" : 2,

"key" : {

"_id" : 1

},

"name" : "_id_",

"ns" : "bianchengbang.posts"

},

{

"v" : 2,

"key" : {

"_fts" : "text",

"_ftsx" : 1

},

"name" : "post_text_text",

"ns" : "bianchengbang.posts",

"weights" : {

"post_text" : 1

},

"default_language" : "english",

"language_override" : "language",

"textIndexVersion" : 3

}

]

通过运行结果可以看出,我们前面创建的索引的名称为“post_text_text”,接下来就可以使用 dropIndex() 方法来删除指定的索引了,如下所示:

> db.posts.dropIndex("post_text_text")

{ "nIndexesWas" : 2, "ok" : 1 }