如何在Amazon S3存储桶中搜索文件内容而无需下载文件

5
我有许多文件上传到Amazon S3,需要根据其内容中字符串的出现情况进行搜索。我尝试了从S3存储桶下载文件并将输入流转换为字符串,然后在内容中搜索该单词的方法,但是如果有五到六个以上的文件,执行上述过程需要很长时间。请问是否有其他方法可以实现此目的?谢谢!

如果你想搜索内容,我认为没有其他选择,只能下载文件。 - Arun P Johny
未来,您可以将文件流式传输到CloudWatch Logs中,而不是仅将其存档在S3上,或者同时进行。然后,您可以轻松搜索它们的内容。https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html - Jeff
7个回答

3
如果您的文件包含CSV、TSV、JSON、Parquet或ORC,您可以查看AWS Athena:https://aws.amazon.com/athena/。根据其介绍,Amazon Athena是一种快速、经济实惠、交互式查询服务,可轻松分析S3中的PB级数据,无需管理数据仓库或集群。但如果您需要搜索纯文本,则不太可能有帮助。我提到它是因为它可能会帮助其他人解决类似的问题。

1
请不要这样做。Athena可以查询结构化文件(CSV、JSON等)生成报告。要进行全文搜索,请使用AWS Elastic或AWS CloudSearch。 https://dev59.com/Xl4b5IYBdhLWcg3w5VT9 - Alex from Jitbit

2

不行!

如果您无法从对象元数据(如文件名)推断匹配项的位置,则只能手动下载和搜索。如果您有闲置带宽,建议同时下载几个文件以加快速度。


2

不能!

我认为可以提高性能的方法是将文件在本地缓存,这样就不必一遍又一遍地下载文件。

你可以使用 Last-Modified 头来检查本地文件是否已更改,然后再次下载它。


我无法将文件存储在本地,因为每个人都无法下载该文件,他们只能查看它。如果我将其存储在本地,用户就可以访问它,因此我不能将其存储在本地。 - Ekata
你是从服务器端还是客户端进行搜索? - Arun P Johny
客户端。就像一个基于内容筛选文件的屏幕,用户将输入一个字符串,我必须获取存储桶中的所有文件并搜索每个文件的内容以查找该字符串。 - Ekata
1
@Ekata: *"无法下载文件,只能查看"*:我希望这不是一个安全要求,因为让我告诉你,如果客户端可以查看文件,通常他们也可以将其存储到硬盘上,即使需要修改客户端软件才能实现... - thkala
但是如果我只获取输入流,而不在文件上使用写入函数,我猜它将不会存储在本地! - Ekata

1
是的,现在使用AWS S3 Select就可以实现。如果您的对象存储在CSV、JSON或Apache Parquet格式中。
AWS详情:https://aws.amazon.com/blogs/developer/introducing-support-for-amazon-s3-select-in-the-aws-sdk-for-javascript/ Aws S3 Select入门示例:https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-select.html 只是如果有人正在寻找相同的东西。
例如,使用SDK:
如果您有一个如下所示的CSV:

user_name,age
jsrocks,13
node4life,22
esfuture,29
...

例如,我们想要检索类似以下内容的东西:
SELECT user_name FROM S3Object WHERE cast(age as int) > 20

然后在JavaScript的AWS SDK中,我们执行以下操作:

const S3 = require('aws-sdk/clients/s3');
const client = new S3({
    region: 'us-west-2'
});

const params = {
    Bucket: 'my-bucket,
    Key: 'target-file.csv',
    ExpressionType: 'SQL,
    Expression: 'SELECT user_name FROM S3Object WHERE cast(age as int) > 20',
    InputSerialization: {
        CSV: {
            FileHeaderInfo: 'USE',
            RecordDelimiter: '\n',
            FieldDelimiter: ','
        }
    },
    OutputSerialization: {
        CSV: {}
    }
};


除非你有一个需要搜索文件中的一个小片段的用例(想要一个子集的结果),否则这不是一个好的选择。我被引导到这个用例,我只是不想下载一个多GB的文件并一次性存储在内存中。显然,流式传输是解决这个问题的方法。 - undefined

1
我的建议是,既然你似乎拥有这些文件,那么就可以根据内容手动进行索引。如果每个文件都有很多“关键词”或元数据,可以使用轻量级数据库来帮助自己执行查询并获取用户正在寻找的确切文件。这将节省带宽并且速度更快,代价是需要维护一种“索引”系统。
另一种选择(如果每个文件没有太多元数据)是重新组织您的存储桶中的文件,并添加前缀以“自动索引”它们,如下所示:
/foo/bar/randomFileContainingFooBar.dat /foo/zar/anotherRandomFileContainingFooZar.dat。
这样,您可能需要扫描整个存储桶才能找到所需的文件集(这就是我建议仅在具有少量元数据时才使用此选项的原因),但您只会下载匹配的文件,这仍然比您最初的方法要好得多。

0

-5

我不熟悉 Amazon S3,但处理搜索远程文件的一般方法是使用indexing,索引本身存储在远程服务器上。这样,每次搜索都会使用索引来推断相对较小的潜在匹配文件数量,只有这些文件会被直接扫描以验证它们是否确实符合条件或不符条件。根据您的搜索条件和模式的复杂性,甚至可能可以完全避免直接扫描文件。

话虽如此,我不知道 Amazon S3 是否有可供使用的索引引擎,也不知道是否有补充库可以帮助你完成这项工作,但这个概念足够简单,你应该能够在不费太多力气的情况下自己实现它。

编辑:

通常,每个文件中存在的标记是被索引的。例如,如果您想搜索"foo bar",索引将告诉您哪些文件包含"foo",哪些文件包含"bar"。这些结果的交集将是同时包含"foo""bar"的文件。您将需要直接扫描这些文件以选择那些(如果有)其中"foo""bar"按正确顺序紧挨在一起的文件。

无论如何,下载到客户端的数据量都比下载和扫描所有内容要少得多,尽管这也取决于您的文件结构和搜索模式的样子。


但是我猜只能使用索引来搜索元数据,而不能搜索完整内容。 - Ekata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接