8

我正在制作一个需要反向搜索的应用程序。我的意思是应用程序的用户将输入搜索参数并保存它们;然后,当任何新对象进入系统时,如果它们与用户保存的现有搜索参数匹配,则会发送通知等。

我很难为这类问题找到解决方案。

我正在使用 Django 并考虑构建搜索并使用 Q 对象对它们进行酸洗,如下所述:http: //www.djangozen.com/blog/the-power-of-q

我看到它的方式,当一个新对象输入数据库时​​,我将不得不从数据库中加载每个保存的查询,并以某种方式对这个新对象运行它,看看它是否会匹配那个搜索查询......这个似乎并不理想 - 以前有没有人解决过这样的问题?

4

3 回答 3

4

您用于解决此问题的工作量与您正在处理的存储查询的数量直接相关。

20 多年前,我们通过将存储查询视为迷你文档并根据所有必须拥有可能拥有的术语对它们进行索引来处理存储查询。新文档的术语列表被用作针对此“查询数据库”的一种查询,并构建了一个可能感兴趣的搜索列表以运行,然后仅针对新文档运行这些搜索。这听起来可能令人费解,但是当存储的查询数量超过几个(比如从 10,000 到 1,000,000 或更多)并且您拥有支持布尔和基于相似性搜索混合的复杂查询语言时,它大大减少了我们的数量必须作为完整的查询执行——通常不超过 10 或 15 个查询。

有帮助的一件事是我们控制了整个事物的水平和垂直方向。我们使用我们的查询解析器构建了一个解析树,它用于构建我们索引查询下的必须/可能有术语的列表。我们警告客户不要在存储的查询中使用某些类型的通配符,因为这可能会导致所选查询数量激增。

更新评论:

简短的回答:我不确定。

更长的答案:我们正在处理一个自定义构建的文本搜索引擎,它的部分查询语法允许以某些方式非常有效地对文档集合进行切片,特别强调date_added. 我们玩了很多游戏,因为我们每天要摄取 4-10,000,000 个新文档,并在具有 64MB 主内存的 DEC Alphas 上针对多达 1,000,000 多个存储查询运行它们。(这是在 80 年代末/90 年代初。)

我猜想对等价的东西进行过滤date_added可以结合您上次运行查询的日期,或者可能是id最后一次查询运行时间的最高日期来完成。如果您需要针对修改后的记录重新运行查询,您可以将其id用作查询的一部分。

为了让我更具体,您将不得不具体地了解您正在尝试解决的问题以及您正在尝试完成的解决方案的规模。

于 2010-03-12T15:31:25.247 回答
4

在数据库级别,许多数据库提供“触发器”。

另一种方法是定时作业,定期从数据库中获取自上次运行以来具有最后修改日期的所有项目;然后这些被过滤并发出警报。您也许可以将一些过滤放入数据库中的查询语句中。但是,如果在删除项目时需要发送通知,这会有点棘手。

您还可以将触发器手动放入将数据提交到数据库的代码中,这可能更灵活,并且当然不依赖于数据库的特定功能。

触发器和警报通信的一个好方法是通过消息队列 - RabbitMQ和其他AMQP实现等队列将随您的站点扩展。

于 2010-03-12T08:16:57.907 回答
1

如果您将每个存储的搜索中涉及的对象类型存储为通用关系,则可以将保存后信号添加到所有涉及的对象。当信号触发时,它只查找涉及其对象类型的搜索并运行这些搜索。如果您有大量的数据库写入和大量保存的搜索,那可能仍然会遇到扩展问题,但这将是一种简单的 Django 方法。

于 2010-03-12T23:10:14.837 回答