mongodb text search创建全文索引,第二个参数必须是text么

00:17 提问
mongodb全文索引对中文的支持
请问,mongodb的全文索引可以用来索引中文吗?比如,我存储的是“北京天安门”,建立全文索引,可以通过db.xxx.fins({$text:{$search:"天安"}})查询出这条数据吗?我自己尝试没成功,必须查询“北京天安门”才能查存出这条数据。难道是对不支持中文?用正则可以实现模糊查询,全文索引不可以吗?
按赞数排序
找一个中文分词库,把分词存到类似 tags 的数据中
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!
其他相关推荐Mongodb全文搜索实战 - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
在传统的关系型数据库中,我们通常将数据结构化,通过一系列表关联、聚合来查询我们所需的结果。而在非结构化的数据中,缺少这种预定义的结构,因而如何快速查询定位到我们所需要的结果,不是一件容易的事。
Mongodb作为一种NoSQL数据库,非常适合存储和管理非结构化数据,例如互联网上的各种文本数据。假如我们用Mongodb存储了很多博客文章,那么如何快速找到所有关于“nodejs”这个主题的文章呢?Mongodb内建的全文搜索可以帮助我们完成这个功能。
在本篇博文中,将要介绍的是我使用Mongdb text search的一些经验。
Mongodb text search是什么?
Mongodb text search是Mongodb对数据库进行搜索的功能模块,类似于数据库内建的搜索引擎。有些人可能会疑问,查数据库为什么还需要搜索引擎?直接用条件查询不就得了。例如在前面的文章主题搜索中,我们不可能事先提取出每篇文章的主题,然后用专门的字段存储,因此没办法进行条件查询。并且同一个主题词,有多种不同的表达方式,例如&node&、&nodejs&可视为同一个主题。
Mongodb text search可以自动地对大段的文本数据进行分词处理、模糊匹配、同义词匹配,解决文本搜索的问题。
建立文本索引
要使Mongodb能够进行全文搜索,首先要对搜索的字段建立文本索引。建立文本索引的关键字是text,我们既可以建立单个字段的文本索引,也可以建立包含多个字段的复合文本索引。需要注意的是,每个collection只能建立一个文本索引,且只能对String或String数组的字段建立文本索引。
我们可以通过以下命令,建立一个文本索引:
db.collection.createIndex({ subject: &text&, content: &text& })
在mongoose中我们可以通过以下代码,创建文本索引:
schema.index({ subject: &text&, content: &text& })
需要注意的是,由于每个collection只支持一个文本索引,所以当你需要在schema中添加或删除文本索引字段时,往往不起作用。这时候你需要到数据库中,手动删除已经建立的文本索引。
文本搜索示例
文本搜索的语法为:
$search: &string&,
$language: &string&,
$caseSensitive: &boolean&,
$diacriticSensitive: &boolean&
在mongoose中,我们可以通过以下语句进行文本搜索:
var query = model.find({ $text: { $search: &hello world& } })
$search后面的关键词可以有多个,关键词之间的分隔符可以是多种字符,例如空格、下划线、逗号、加号等,但不能是-和\&,因为这两个符号会有其他用途。搜索的多个关键字是or的关系,除非你的关键字包含-。例如hello world会包含所有匹配hello或world的文本,而hello -world只会匹配包含hello且不包含world的文本。
$language指示搜索的语言类型,在最新的Mongodb 3.2 enterprise版本中,已经增加了对中文文本的搜索。
$caseSensitive设置是否区分大小写。
$diacriticSensitive设置是否区别发音符号,CAF?于Café是同一语义,只是重音不一样。
我们还可以对搜索的结果按匹配度进行排序:
db.posts.find(
{ $text: { $search: &hello world& } },
{ score: { $meta: &textScore& } }
).sort( { score: { $meta: &textScore& } } )
Mongodb建立文本索引时,会对提取所有文本的关键字建立索引,因而会造成一定的性能问题。所以对于结构化的字段,建议用普通的关系查询,如果需要对大段的文本进行搜索,才考虑用全文搜索。
把读和写分开就好。建立全文检索在只读的数据库里就没有问题了
桑大说得有道理。但是我心里一直有些顾虑,就是全文搜索应该是搜索引擎干的事,数据库集成一个搜索引擎是不是有点狗拿耗子的感觉。
看场景吧,如果你的量不是特别大,上个搜索引擎比如elastic search这样的,不是太重了么?
现在做带全文检索功能并且搜索权重比较高的应用,可以先考虑ElasticSearch,ES基本上已经是一个MongoDB的超级,原生的搜索架构集成,比在MongoDB里做是成熟更多的方案。你也可以用Mongo-ES connect,同事用两者,但没有直接用ES好。
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的MongoDB 全文搜索教程 - 技术翻译 - 开源中国社区
MongoDB 全文搜索教程
【已翻译100%】
英文原文:
推荐于 5年前 (共 9 段, 翻译完成于 01-11)
参与翻译&(5人)&: ,
在我的那篇一文中,我们已经对MongoDB的基本功能有了一个初步的了解。今天,通过这篇文章,我们来更进一步的讨论MongoDB全文检索功能。
你会发现全文搜索并非是通过find()命令实现,而是通过调用
db.foo.runCommand( "text", {search: "bar"} ) 请牢记这个命令现在还处于实验阶段。通过这个命令实现find()功能,会在生产环境中掺入危险的代码。通过runCommand()这个命令来执行搜索,运行和测试可以实现分离。
我多么的希望一个新的检索操作符,例如$textor $textsearch 可以和标准的find()命令相结合。
&翻译得不错哦!
文本检索语法
在前面的例子中,我们只是搜索一个单词。我们可以搜索的更复杂一些,让我们来看看以下代码:
db.foo.drop()
db.foo.ensureIndex( {txt: "text"} )
db.foo.insert( {txt: "Robots are superior to humans"} )
db.foo.insert( {txt: "Humans are weak"} )
db.foo.insert( {txt: "I, Robot - by Isaac Asimov"} ) 搜索单词“robot”, 会得到2个结果,而搜索“human”结果也是2个。
& db.foo.runCommand("text", {search: "robot"}).results.length
& db.foo.runCommand("text", {search: "human"}).results.length
2 当我们搜索条件包含多个单词,数据库会执行或的操作,搜索结果会得到3个。
& db.foo.runCommand("text", {search: "human robot"}).results.length
3 我希望搜索的单词之间是与的关系而不是或的关系。
&翻译得不错哦!
通过在搜索单词前加上减号'-',可以在搜索的时候,排除包含该单词的记录。也就是说,我们需要搜索包含“robot”,但是不包含“humans”的记录。
& db.foo.runCommand("text", {search: "robot -humans"})
"queryDebugString" : "robot||human||||",
"language" : "english",
"results" : [
"score" : 0.6666,
"_id" : ObjectId("50ebce88aaa4ada0"),
"txt" : "I, Robot - by Isaac Asimov"
"stats" : {
"nscanned" : 2,
"nscannedObjects" : 0,
"timeMicros" : 212
通过用引号包含由多个单词组成的词组(“foo bar”),就可以实现词组搜索。在词组里面,单词的顺序十分重要,同时搜索结束单词也需要考虑。
& db.foo.runCommand("text", {search: '"robots are"'})
"queryDebugString" : "robot||||robots are||",
"language" : "english",
"results" : [
"score" : 0.6666,
"_id" : ObjectId("50ebce88aaa4ad9e"),
"txt" : "Robots are superior to humans"
"stats" : {
"nscanned" : 2,
"nscannedObjects" : 0,
"timeMicros" : 185
} 请查看如下的例子"queryDebugField"
"queryDebugString" : "robot||||robots are||" 我们需要搜索条件中包含"robot"的词根,同时也包含"robots are"的词组。这就是为什么我们只找到一条记录。请比较如下的搜索:
& // order matters inside phrase
& db.foo.runCommand("text", {search: '"are robots"'}).results.length
& // no phrase search --& OR query
& db.foo.runCommand("text", {search: 'are robots'}).results.length
&翻译得不错哦!
多语言支持
分词和停用词过滤都是与语言有关的。如果你希望用英语以外的语言来创建索引和搜索,那么必须告诉MongoDB。MongoDB用的是开源的分词器,它支持这些语言。
如果希望使用其它语言,需要在创建索引时这样写:
db.de.ensureIndex( {txt: "text"}, {default_language: "german"} )
MongoDB就会认为“txt”中的文本是德语,而且我们搜索的文本也是德语。我们看看是不是这样的:
& db.de.insert( {txt: "Ich bin Dein Vater, Luke." } )
& db.de.validate().keysPerIndex["text.de.$txt_text"]
&翻译得不错哦!
如你所见,这里只有两个索引关键字,因此停用词过滤就会起效(这里用的是德语的停用词,Vater 是德语中的 father 意思
) ,我们再试试其他一些搜索:
db.de.insert( {language:"english", txt: "Ich bin ein Berliner" } )
请注意,我们不一定需要在搜索的时候提供语言,因为这是从索引继承而来。我们已经命中了同义词 Vater 和 Luke,但没有命中停用词 ich (意思是 I)
我们还可以在同一个索引中混合多种不同的语言,每个文档都有它独立的语言:
db.de.insert( {language:"english", txt: "Ich bin ein Berliner" } )
&翻译得不错哦!
如果存在 “language” 字段,其内容就相当于为文档的索引数据定义了流数据的语言和停用词过滤。单词 ich 在英语中并不是停用词,因此它被索引了。
// default language: german -& no hits
& db.de.runCommand("text", {search: "ich"})
"queryDebugString" : "||||||",
"language" : "german",
"results" : [ ],
"stats" : {
"nscanned" : 0,
"nscannedObjects" : 0,
"timeMicros" : 96
// search for English -& one hit
& db.de.runCommand("text", {search: "ich", language: "english"})
"queryDebugString" : "ich||||||",
"language" : "english",
"results" : [
"score" : 0.625,
"_id" : ObjectId("50ed163b1e27d5e73741fafb"),
"language" : "english",
"txt" : "Ich bin ein Berliner"
"stats" : {
"nscanned" : 1,
"nscannedObjects" : 0,
"timeMicros" : 161
这里到底发生什么事情?默认的搜索语言是德语,因此首次搜索没有返回任何结果。而第二次搜索时,我们搜索英语文本,这也是为什么我们能从这个句子中找出 JFK。
这是什么意思呢?嗯,你已经有了这种的多语言文本搜索,你可以在一个集合中存储来自全世界不同语言的文本信息,然后仍然使用你的母语进行搜索。
&翻译得不错哦!
文本索引可以跨越多个字段。在这种情况下,每个字段可以有自己的权重。我们可以利用权重,为文档的不同的部分赋予不同的意义。
& db.mail.ensureIndex( {subject: "text", body: "text"}, {weights: {subject: 10} } )
& db.mail.getIndices()
"_fts" : "text",
"_ftsx" : 1
"ns" : "de.mail",
"name" : "subject_text_body_text",
"weights" : {
"body" : 1,
"subject" : 10
"default_language" : "english",
"language_override" : "language"
] 我们创建了一个跨越两个字段的文本索引,“subject”和“body”,它们的权重分别是10和1。我们看下权重有什么影响:
& db.mail.insert( {subject: "Robot leader to minions", body: "Humans suck", prio: 0 } )
& db.mail.insert( {subject: "Human leader to minions", body: "Robots suck", prio: 1 } )
& db.mail.runCommand("text", {search: "robot"})
"queryDebugString" : "robot||||||",
"language" : "english",
"results" : [
"score" : 6.666,
"_id" : ObjectId("50ed1be71e27d5e73741fafe"),
"subject" : "Robot leader to minions",
"body" : "Humans suck"
"prio" : 0
"score" : 0.75,
"_id" : ObjectId("50ed1bfd1e27d5e73741faff"),
"subject" : "Human leader to minions",
"body" : "Robots suck"
"prio" : 1
"stats" : {
"nscanned" : 2,
"nscannedObjects" : 0,
"timeMicros" : 148
} 可以看到,“subject”字段含有“robot”的文档会有更高的得分,那是因为它有10的权重,作为倍数乘了上去。
&翻译得不错哦!
过滤与投射
我们还可以利用过滤来附加额外的搜索条件:
& db.mail.runCommand("text", {search: "robot", filter: {prio:0} } )
"queryDebugString" : "robot||||||",
"language" : "english",
"results" : [
"score" : 6.666,
"_id" : ObjectId("50ede73741fb04"),
"subject" : "Robot leader to minions",
"body" : "Humans suck",
"prio" : 0
"stats" : {
"nscanned" : 2,
"nscannedObjects" : 2,
"timeMicros" : 185
} 需要注意的是,过滤并不会使用索引。
如果我们关心的只是一部分字段,可以使用投射(类似于汇聚框架):
& db.mail.runCommand("text", {search: "robot", projection: {_id:0, prio:0} } )
"queryDebugString" : "robot||||||",
"language" : "english",
"results" : [
"score" : 6.666,
"subject" : "Robot leader to minions",
"body" : "Humans suck"
"score" : 0.75,
"subject" : "Human leader to minions",
"body" : "Robots suck"
"stats" : {
"nscanned" : 2,
"nscannedObjects" : 0,
"timeMicros" : 127
} 过滤和投射是可以一起使用的。
&翻译得不错哦!
我们在这篇文章里学习了MongoDB文本搜索的一些有趣功能。它应该对我们实现搜索引擎有很好的帮助。期待大家的反馈。
&翻译得不错哦!
我们的翻译工作遵照 ,如果我们的工作有侵犯到您的权益,请及时联系我们
说的很有条理,赞一个!!!不过最后的example根据上下文翻译成代码也还好高效开源数据库(mongodb)下载V3.4.10 官方正式版_西西软件下载
西西软件园多重安全检测下载网站、值得信赖的软件下载站!
相关软件 /中文/ /英文/ /英文/ /中文/ /中文/ /英文/ /中文/ /中文/ /英文/ /中文/顶好评:50%踩坏评:50%请简要描述您遇到的错误,我们将尽快予以修正。轮坛转帖HTML方式轮坛转帖UBB方式
64.9M/中文/4.4
3.6M/英文/5.4
19.0M/中文/4.8
1.82G/中文/5.1
12.1M/中文/5.1
386M/英文/8.2
203M/中文/5.1
MongoDB是一个介于关系和非关系数据库之间的产品, 是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。 Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持 对数据建立索引。之所以喜欢MongoDB,主要是因为在动态语言中使用它是如此的简单,自然。到目前为止,我已经在两个项目(Encode 和 Sparrw)中使用过它了,虽然对这个选择我非常满意,但是有些问题我还是没有注意到,这些问题让我抓了好几个小时的头皮才解决。如果你有多台机器,然后为数据库多分配几台机器,那么有些问题可以迎刃而解,但是我的项目是运行在单个(虚拟)服务器之上的低流量Web应用程序。MongoDB服务端可运行在Linux、Windows或OS X平台,支持32位和64位应用,默认端口为27017。推荐运行在64位平台,因为MongoDB在32位模式运行时支持的最大文件尺寸为2GB。MongoDB把数据存储在文件中(默认路径为:/data/db),为提高效率使用内存映射文件进行管理。安装配置:MongoDB默认的数据目录为:C:\data\db。如果不用默认目录,则需要在在mongod.exe命令后加--dbpath参数。创建数据目录。我创建的是D:\dev\mongodb-win32-x86_64-2.4.5\data\db创建日志目录及其文件。我创建的是D:\dev\mongodb-win32-x86_64-2.4.5\log及D:\dev\mongodb-win32-x86_64-2.4.5\log\log.txt。1、启动MongoDB打开cmd窗口(cmd.exe),进入D:\dev\mongodb-win32-x86_64-2.4.5\bin,执行mongod.exe命令,见下图。mongod.exe --logpath=D:\dev\mongodb-win32-x86_64-2.4.5\log\log.txt --dbpath=D:\dev\mongodb-win32-x86_64-2.4.5\data\db!--logpath 参数是设定日志文件的路径。--dbpath 参数是设定数据库文件的存放路径。mongod.exe命令的所有参数选项可通过mongod.exe --help查看。2、作为服务进行安装使用管理员权限打开windows的cmd窗口,进入D:\dev\mongodb-win32-x86_64-2.4.5\bin目录。mongod.exe --install --logpath=D:\dev\mongodb-win32-x86_64-2.4.5\log\log.txt --dbpath=D:\dev\mongodb-win32-x86_64-2.4.5\data\db--install 参数是设定安装为服务器!设置为服务后,即可在cmd(管理员权限打开的windows cmd窗口)窗口用服务的方式启动或停止MongoDB。net start mongodb 启动mongodb服务net stop mongodb 启动mongodb服务3、进入shell环境界面进入sheelMongoDB后,在cmd窗口进入D:\dev\mongodb-win32-x86_64-2.4.5\bin目录,输入mongo.exe,则可以进入shell环境界面。主要功能:面向集合存储,易存储对象类型的数据。模式自由。支持动态查询。支持完全索引,包含内部对象。支持查询。支持复制和故障恢复。使用高效的二进制数据存储,包括大型对象(如视频等)。自动处理碎片,以支持云计算层次的扩展性支持RUBY,PYTHON,JAVA,C++,PHP等多种语言。文件存储格式为BSON(一种JSON的扩展)可通过网络访问更新日志:MongoDB 2.6 已经在今天发布,当然,关注MongoDB的同志自然知道这个消息。整个MongoDB2.6,个人觉得认证系统是一个重新设计的系统。当然,MongoDB 2.4.6开始,就已经在尝试新的基于Role的认证方式了,但是真正的成熟还是在2.6.0这个版本。TextSearch全文检索这个功能在 2.4.6里面就有的功能,这次的变化是,将这个TextSearch的放入了Aggerate里面了。换句话说,原来的全文检索的结果是孤立的,现在可以作为聚合检索的一个部分了,文本检索的结果可以作为其他聚合操作的输入数据。作为MongoDB5年里程碑的这个版本,还有其他很多对以往功能的增强。作为一个长期观察MongoDB的人来说,我个人认为,现在是大家可以尝试MongoDB的一个时间点了。2.6.0以前的版本的确有很多诟病,除了前面说过的读写的安全之外,还有很多设计上的问题。经过2.4的很多演化后,很多东西都定型了:主从(Master-Slaver)模型 被 Replication模型代替加入基于Role的认证后,可以自定义角色(当然,系统也有一些内置的角色)全文检索(很遗憾,不支持中文)的强化 具有特色的 地理聚合(很多处理地理坐标的内置函数)TLL数据集(数据集里面的记录会慢慢自动删除掉,有点缓存的意思)Capped数据集(固定大小的数据集,在存储和读写上提高效率,牺牲灵活性)Sharding支持了ShardKey索引的内容丰富了不少,特别是有了text属性的索引,对于全文检索的帮助很大MongoDB的2.4已经发布,其中包括新的功能,如文本搜索,基于散列的分片。主要功能和增强功能:基于散列分片Capped&阵列文本搜索(测试版)地理空间增强更快的计数聚合框架的改进基于角色的权限工作集分析器改进复制什么是基于角色Role的认证系统?在以往的MongoDB中,官方一直推荐MongoDB应该在一个Trust的环境下运行,对于认证和安全性上的考虑是不充分的。(MongoDB的安全性和读写的完整性以前一直被人诟病,WriteConcern解决了写数据的安全性,这次的RoleBase的认证机制,在一定程度上提高了MongoDB的安全性)现在在MongoDB中创建的User,除了有用户名,密码等传统属性之外,还有一个Role的概念。每个Role的操作权限是不同的,而且,根据细化的配置,可以将每个Role的权限定义的非常详细,Role可以查询,修改某个数据库,某个数据表,都可以做到小粒度的定义。每个用户可以同时拥有多个Role,这样的话,管理员可以对于各个用户的权限做到非常精确的控制了。MongoDB的 具体实现 Role:每个Role可以有多个Privilege,每个Privilege指定了可以访问的资源(可以指定数据集,数据库,精确到具体的某个数据集)对于资源的可以执行的操作(Action),例如 数据集的查找 或者 更新。对于各种的操作已经做到非常小的粒度的细化了。例如 添加用户 和 删除用户 已经是两个操作了(Action),而不是通常理解的,增删改是同样的操作。(当然,可能也有人认为如此细化对于管理者来说也是一种负担。不过一个Role一旦精心设计之后,就可以分配给不同用户,一劳永逸了)
安卓官方手机版
IOS官方手机版
数据库管理软件是一种负责数据库的定义、建立、操作、管理和维护的软件系统。它对数据库进行统一的管理和控制,以保证数据库的安全性和完整性。用户通过DBMS访问数据库中的数据,数据库管理员也通过dbms进行数据库的
英文 / 5.8MMyDB Studio包含了用于MySQL服务
英文 / 18.7Mdbforge studio for mysql是一款
英文 / 6.1MSequel Pro for Mac是一款Mac平台
英文 / 27.6MMySQLWorkbench是一款专为MySQL设
多国语言[中文] / 579.6MPentaho Data Integration (Kett
英文 / 22.1MNavicatDataModeler中文破解版是
高效开源数据库(mongodb) V3.0.6 官方正式版
高效开源数据库(mongodb) V3.4.10 官方正式版 【x64】
下载帮助西西破解版软件均来自互联网, 如有侵犯您的版权, 请与我们联系。没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!

我要回帖

更多关于 solr mongodb全文索引 的文章

 

随机推荐