【问题标题】:Search keywords in files stored in mongodb在存储在 mongodb 的文件中搜索关键字
【发布时间】:2014-06-21 05:12:15
【问题描述】:

我使用 gridFS 和 node.js 在 mongodb 中存储了一个 .txt 文件。 我们可以存储 .pdf 和其他格式吗?当我尝试存储 .pdf 并在控制台上检索内容时,它会在文档中显示文本并在其中显示一些垃圾值。我用这一行来检索“GridStore.read(db,id,function(err, fileData)” 还有其他更好的方法吗?

我们可以直接对存储在mongodb中的文件的内容进行文本搜索吗?如果是这样,我们该怎么做?

另外你能告诉我存储在mongodb中的文件数据在哪里以及以什么格式? 在这方面的任何帮助都会很棒。 --谢谢

【问题讨论】:

    标签: node.js mongodb file mongodb-query gridfs


    【解决方案1】:

    您真正想要的是“文本搜索”功能,在 MongoDB 中,您只需将“文本”存储在文档中的一个或多个字段中即可。将“文本”放入 MongoDB 非常简单,因为您只需提供“文本”作为字段的内容,MongoDB 就会存储它。几乎任何类型的其他数据也是如此,它们只会存储在您指定的字段下。

    这里的一般情况是您似乎确实想要“文本搜索”,因此您必须存储数据的“文本”。但在实现之前,让我们先谈谈 GridFS 究竟是什么,以及它不是什么,以及它肯定不是你想的那样。


    GridFS

    GridFS 不是 MongoDB 的软件或特殊功能。实际上,它是由可用驱动程序实现的功能规范,其唯一目的是使您能够存储超过 16MB BSON 存储限制的内容。

    为此,实现使用了两个集合。默认情况下,它们被命名为fs.filesfs.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,那么只需像往常一样将其存储在文档中即可。但是当然,如​​果那是二进制数据而不是文本,那么除非您明确提取文本,否则搜索对您没有好处。

    【讨论】:

      猜你喜欢
      • 2015-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多