ChatGPT解决这个技术问题 Extra ChatGPT

用于过滤应用程序的弹性搜索与 MongoDB [关闭]

关闭。这个问题是基于意见的。它目前不接受答案。想改进这个问题?更新问题,以便可以通过编辑这篇文章用事实和引用来回答它。 7年前关闭。改进这个问题

这个问题是关于在深入研究实验和实现的细节之前做出架构选择。这是关于弹性搜索与 MongoDB 在可扩展性和性能方面的适用性,用于某种特定目的。

假设两者都存储具有字段和值的数据对象,并允许查询该对象主体。因此,可能根据临时选择的字段过滤掉对象的子集,这对两者都适用。

我的应用程序将围绕根据标准选择对象展开。它将通过同时过滤多个字段来选择对象,换句话说,它的查询过滤条件通常包括 1 到 5 个字段,在某些情况下可能更多。而选择作为过滤器的字段将是大量字段的子集。想象一下现有的大约 20 个字段名称,每个查询都是尝试从这 20 个字段中的几个字段过滤对象(它可以少于或超过 20 个整体字段名称,我只是使用这个数字来演示字段到在每个离散查询中用作过滤器的字段)。过滤可以通过所选择的字段的存在,也可以通过字段值来进行,例如过滤掉具有字段A,并且它们的字段B在x和y之间,并且它们的字段C等于w的对象。

我的应用程序将不断地进行这种过滤,而在任何时候哪些字段用于过滤方面都没有任何或很少的常数。也许在 elasticsearch 中需要定义索引,但即使没有索引,速度也可能与 MongoDB 相当。

根据进入存储的数据,没有关于此的特殊细节..对象在插入后几乎不会更改。也许需要删除旧对象,我想假设两个数据存储都支持在内部或通过应用程序查询过期删除内容。 (不太常见的是,适合某个查询的对象也需要被删除)。

你怎么看?而且,你有没有尝试过这个方面?

对于此类任务,我对两个数据存储中的每一个的性能和可扩展性感兴趣。这是一种架构设计问题,欢迎使用商店特定选项或查询基石的详细信息来使其架构良好,作为经过深思熟虑的建议的演示。

谢谢!

我不知道为什么这不断获得选票,经过这么长时间,它们是否如此突出?
只是有趣的是,您 6 年前选择了什么,到目前为止您的经验是什么:)?
更新 - 对于那些好奇此答案是否仍然相关的人,MongoDB 现在具有全文索引,以提供与所选答案中描述的弹性搜索相同的功能和优势。它们存储为单独的索引,可以根据需要进行查询,但您不会失去拥有通用数据库的任何好处。去年我一直将 MongoDB 用于一般用途和文本搜索查询,并强烈推荐它。只是我的两分钱。

g
gstathis

首先,这里有一个重要的区别:MongoDB 是一个通用数据库,Elasticsearch 是一个由 Lucene 支持的分布式文本搜索引擎。人们一直在谈论使用 Elasticsearch 作为通用数据库,但知道这不是它的原始设计。我认为通用 NoSQL 数据库和搜索引擎正在走向整合,但就目前而言,两者来自两个截然不同的阵营。

我们在我的公司中同时使用 MongoDB 和 Elasticsearch。我们将数据存储在 MongoDB 中,并专门使用 Elasticsearch 来实现其全文搜索功能。我们只将需要查询的 mongo 数据字段的一个子集发送到 elastic。我们的用例与您的用例不同,因为我们的 Mongo 数据一直在变化:一条记录或一条记录的字段的子集,每天可以更新几次,这可能需要将该记录重新索引为弹性。仅出于这个原因,使用弹性作为唯一的数据存储对我们来说不是一个好选择,因为我们无法更新选择字段;我们需要重新索引整个文档。这不是弹性限制,这就是 Lucene 的工作方式,弹性背后的底层搜索引擎。在您的情况下,记录一旦存储就不会更改的事实使您不必做出选择。话虽如此,如果数据安全是一个问题,我会三思而后行使用 Elasticsearch 作为数据的唯一存储机制。它可能会在某个时候到达那里,但我不确定它是否还在那里。

在速度方面,Elastic/Lucene 不仅与 Mongo 的查询速度相当,在您的情况下,“在任何时候用于过滤的字段几乎没有固定不变”,它可能是幅度更快,尤其是当数据集变得更大时。区别在于底层查询实现:

Elastic/Lucene 使用向量空间模型和倒排索引进行信息检索,这是将记录相似性与查询进行比较的高效方法。当你查询 Elastic/Lucene 时,它已经知道答案了;它的大部分工作在于按最有可能与您的查询词匹配的结果为您排名。这一点很重要:搜索引擎,而不是数据库,不能保证你得到准确的结果;他们根据与您的查询的接近程度对结果进行排名。碰巧的是,大多数时候,结果接近准确。

Mongo 的方法是更通用的数据存储。它将 JSON 文档相互比较。您可以通过各种方式获得出色的性能,但您需要仔细设计索引以匹配您将运行的查询。具体来说,如果您有多个要查询的字段,则需要仔细制作复合键,以便它们尽可能快地减少要查询的数据集。例如,您的第一个键应该过滤掉大部分数据集,第二个键应该进一步过滤掉剩下的内容,依此类推。如果您的查询与定义的索引中的键和这些键的顺序不匹配,您的性能将会下降很多。另一方面,Mongo 是一个真正的数据库,所以如果您需要准确性,那么它将给出的答案将是准确的。

对于过期的旧记录,Elastic 具有内置的 TTL 功能。我认为 Mongo 刚刚在 2.2 版中引入了它。

由于我不知道您的其他要求,例如预期的数据大小、事务、准确性或过滤器的外观,因此很难提出任何具体建议。希望这里有足够的内容可以帮助您入门。


只是要评论一下,这可能是希望对本网站上的架构主题做出的最高级别的响应。感谢您博学,分析,清晰,并真正参与场景。
关于准确性,您可以通过选择标记化和分析字段的方式来使用 Elastic/Lucene 对其进行控制。如果您的字段未被分析(即分解为空格分隔的术语),您可以强制搜索引擎按原样处理它们。然后,如果您使用术语查询 (elasticsearch.org/guide/reference/query-dsl/term-query.html) 进行查询,则可以确保您只获得完全匹配的结果。这种方法类似于常规数据库如何进行精确匹配。
更新 - 对于那些好奇此答案是否仍然相关的人,MongoDB 现在具有全文索引,以提供与所选答案中描述的弹性搜索相同的功能和优势。它们存储为单独的索引,可以根据需要进行查询,但您不会失去拥有通用数据库的任何好处。去年我一直将 MongoDB 用于一般用途和文本搜索查询,并强烈推荐它。只是我的两分钱。
@JasonRoell 我需要从某人那里听到,互联网上的所有其他文章都是在发布文本索引之前编写的,当时慢速正则表达式是唯一的选择。我很想看看 mongodb 和 elasticsearch 之间的速度比较,
@gstathis 这是我读过的最好的答案之一。感谢您分享您的知识,这非常有帮助。