您真正想要的是“文本搜索”功能,在 MongoDB 中,您只需将“文本”存储在文档中的一个或多个字段中即可。将“文本”放入 MongoDB 非常简单,因为您只需提供“文本”作为字段的内容,MongoDB 就会存储它。几乎任何类型的其他数据也是如此,它们只会存储在您指定的字段下。
这里的一般情况是您似乎确实想要“文本搜索”,因此您必须存储数据的“文本”。但在实现之前,让我们先谈谈 GridFS 究竟是什么,以及它不是什么,以及它肯定不是你想的那样。
GridFS
GridFS 不是 MongoDB 的软件或特殊功能。实际上,它是由可用驱动程序实现的功能规范,其唯一目的是使您能够存储超过 16MB BSON 存储限制的内容。
为此,实现使用了两个集合。默认情况下,它们被命名为fs.files 和fs.chunks,但实际上可以是您告诉旅游驱动程序实现实际使用的任何内容。这些集合存储这些默认名称所指示的内容。作为“文件”和存储
的其他集合的唯一标识符和元数据
以下是您通过 GridFS API 作为“块”集合中的文档发送的数据的快速 sn-p:
{
"_id" : ObjectId("539fc66ac8b5e6dc058b4568"),
"files_id" : ObjectId("539fc66ac8b5e6dc058b4567"),
"n" : NumberLong(0),
"data" : BinData(2,"agQAADw/cGhwCgokZGJ....
}
对于上下文,该数据属于我通过GridFS API 函数发送的“文本”文件。如您所见,尽管实际内容是文本,但这里显示的是原始二进制数据的“散列”形式。
这实际上是 API 函数所做的,通过读取您作为字节流提供的数据并以可管理的“块”提交该二进制流,因此很可能您的“文件”部分不会实际上被保存在同一个文件中。这实际上是实现的重点。
对于 MongoDB 本身,这些只是普通的集合,您可以将它们视为所有常规操作,例如查找、删除和更新。您的驱动程序实现的GridFS API 规范为您提供了从所有这些块中“读取”的功能,甚至可以像返回文件一样返回该数据。但实际上它只是集合中的数据,采用二进制格式,并在文档中拆分。这些都不能帮助您执行“搜索”,因为它既不是“文本”也不是包含在同一个文档中。
文本搜索
所以你真正想要的是“文本搜索”,让你找到你正在搜索的单词。例如,如果您想存储 PDF 文件中的“文本”,则需要从外部提取该文本并存储在文档中。或者使用外部文本搜索系统来做同样的事情。
对于 MongoDB 实现,任何提取的文本都将存储在一个文档中,或者可能存储在多个文档中,以便您启用 "text index" 以启用搜索功能。基本上你会在这样的集合上这样做:
db.collection.ensureIndex({ "content": "text" })
一旦集合中文档上的一个或多个“字段”被文本索引覆盖,那么您就可以使用$text 运算符和.find() 进行实际搜索:
db.collection.find({ "$text": { "$search": "word" } })
这种查询形式允许您根据您在搜索中指定的字词匹配文档,还可以确定与您的搜索的相关性并对文档进行相应的“排名”。
更多信息可以在text search的教程部分找到。
结合
事实上,没有什么能阻止您采取综合方法。在这里,您实际上将使用GridFS API 方法存储您的原始数据文档,然后将提取的“文本”存储在另一个集合中,该集合知道并包含对原始fs.files 文档的引用,该文档引用您的大文本文档或PDF 文件或其他文件。
但是您需要从原始“文档”中提取“文本”并将其存储在您集合中的 MongoDB 文档中。否则,可以对外部文本搜索解决方案采取类似的方法,在这种解决方案中,提供可以执行诸如从 PDF 文档之类的内容中提取文本之类的操作的界面是很常见的。
如果您打算提供原始内容,您还可以使用外部解决方案发送对文档的 GridFS 表单的引用,以允许通过其他请求从任何搜索中检索此数据。
所以最终你会发现这两种方法实际上是针对不同的事情的。您可以围绕“组合”功能构建自己的方法,但“搜索”用于搜索,“块”存储用于完全按照您的意愿进行操作。
当然,如果您的内容始终小于 16MB,那么只需像往常一样将其存储在文档中即可。但是当然,如果那是二进制数据而不是文本,那么除非您明确提取文本,否则搜索对您没有好处。