对于包含字符串的MongoDB字段(例如,州名或省名),在字符串类型字段上创建索引之间存在什么(如果有)差异:
db.ensureIndex( { field: 1 } )
并在该字段上创建文本索引:
db.ensureIndex( { field: "text" }
在这两种情况下,field
属于string
类型。
我正在寻找一种方法,对包含单个单词(可能更多)的文本字段进行不区分大小写的搜索。作为Mongo的新手,我无法区分使用上述两种索引方法,甚至是$regex
搜索。
答案 0 :(得分:29)
两个索引选项非常不同。
在字符串字段上创建常规索引时,它会对其进行索引 字符串中的整个值。对单个单词字符串非常有用 (比如登录用户名)你可以完全匹配。
另一个硬文本索引将标记并阻止其内容 场。所以它会把字符串分成单个单词或 令牌,并将进一步减少他们的茎,使变种 相同的单词将匹配(“谈话”匹配“谈话”,“谈话”和 例如,“说话”,因为“谈话”是所有三个的主干。大多 对真文本有用(句子,段落等)。
文字搜索
文本搜索支持在文档中搜索字符串内容 采集。 MongoDB提供
$text
运算符来执行文本搜索 在查询和聚合管道中。文本搜索过程:
tokenizes and stems the search term(s) during both the index creation and the text command execution. assigns a score to each document that contains the search term in the indexed fields. The score determines the relevance of a document to a given search query.
$text
运算符可以搜索单词和短语。查询匹配 在完整的词干上。例如,如果是文档字段 包含蓝莓这个词,对蓝色一词的搜索不匹配 该文件。但是,搜索蓝莓或蓝莓 会匹配。
$regex
搜索可以与字符串字段上的常规索引一起使用
提供一些模式匹配和通配符搜索。不是很糟糕
索引的有效用户,但它将使用索引:
如果该字段存在索引,则MongoDB与常规索引匹配 表达式对索引中的值,可以比a快 收集扫描。如果常规可以进一步优化 表达式是一个“前缀表达式”,这意味着所有潜力 匹配以相同的字符串开头。这允许MongoDB构建一个 来自该前缀的“范围”仅与来自该前缀的那些值匹配 指数落在该范围内。
http://docs.mongodb.org/manual/core/index-text/
http://docs.mongodb.org/manual/reference/operator/query/regex/
答案 1 :(得分:3)
文本索引允许您搜索文本中的单词。您可以在非文本索引的文本字段上使用正则表达式执行相同操作,但速度会慢得多。
在MongoDB 2.6之前,必须使用自己的命令进行文本搜索操作,这是一个很大的缺点,因为您不能将其与其他过滤器结合使用,也不能将结果视为公共游标。截至目前,文本搜索只是典型find
方法的另一个运算符,而且非常好。
那么,为什么文本索引及其后续搜索比非索引文本字段上的正则表达式更快?这是因为文本索引是一个字典,一个能够在每种语言基础上丢弃单词的聪明的字典(默认为英语)。当您运行文本搜索查询时,您将对字典运行它,从而节省您在整个集合中迭代所花费的时间。
请记住,文本索引会随着您的集合一起增长,并且可能会占用大量空间。使用上限集合时,我学到了很多东西。没有办法限制文本索引。
文本字段上的常规索引,例如
db.ensureIndex( { field: 1 } )
只有在搜索整个文本时,才有用。例如,它用于查找字母数字哈希值。在存储文本段落,短语等时应用这种索引没有任何意义。