5

背景:

代表不同类型事件(音乐会、足球比赛、慈善收藏等)的 SQL 数据库,其中每个都包含与事件相关的数据(音乐会 - 艺术家姓名,比赛 - 主持人/访客团队)。所有这些事件都继承自一个通用表event,其中包含与所有事件相关的数据(名称、描述、位置、开始/结束日期)。继承是使用从HibernateDoctrine已知的 table-per-subclass 模型实现的。数据库还存储在和表中使用的表artistsidnamebirth_date)和football_teamsidnamecountry、 ) (通过 FK)。coach_nameevent_concertsevent_football_matches

问题:

创建一个给定条件({name: "manchester", startDate: "01.01.2012 - 01.02.2012"}{location: "london", description: "artists +metallica -bieber"})的搜索引擎将返回所有符合条件的事件,以及来自artists/football_teams表的结果。

这些事件的某些属性包含大量文本,应以全文搜索方式进行搜索。

例子:

给定以下搜索条件:

{ location: "london", startDate: "05.11.2012 - 07.11.2012" }

搜索引擎应返回:

  1. (足球赛事)阿森纳对曼联的比赛,酋长球场,伦敦,2012 年 11 月 6 日
  2. (音乐会活动)Metallica 音乐会,Some-Fancy-Location,05.11.2012
  3. (足球队/非赛事)阿森纳,成立时间:1886 年,联赛:英超联赛
  4. (足球队/非赛事)切尔西,成立时间:1905 年,联赛:英超联赛
  5. (节日活动)伦敦万圣节,07.11.2012
  6. (舞蹈活动)Sadler's Wells 的睡美人,45 英镑,2012 年 11 月 7 日
  7. (音乐家,不是事件)尼尔·克里斯蒂安,1943 - 2012,摇滚歌手

如您所见,仅在发生事件时才考虑startDate(与事件相关的属性)。


搜索引擎必须扫描大量表,这就是为什么我认为我应该使用专用软件(Sphinx、Lucene、...?)并为搜索创建单独的索引。


任何人都可以建议一些解决方案来构建这样一个索引吗?我可以使用什么软件作为该搜索引擎的基础?


编辑:

只是为了澄清:不需要任何属性。其中一些包含将使用精确匹配搜索的日期,其中一些包含也将使用精确匹配搜索的短文本(如位置)。但其中一些包含长文本,需要以全文方式搜索。

4

5 回答 5

3

我看到了三种方法。

  • 迁移到 Couchdb。要进行location+搜索,请使用as 键start time构建视图。[location, event_start_time]在搜索期间,您使用?startkey=["london,"05.11.2012"]&endkey=["london", "07.11.2012"]. 要启用全文搜索,您可以像这样description构建一个特定的视图。

  • 构建ElasticSearch索引。您示例中的搜索只是使用两个数据字段的结构化查询,其中location是必须的,事件start time是范围。elasticsearch 中的全文搜索功能更强大,您可以定义特定的分析器来处理数据中的文本。Elasticsearch 还支持使用地理空间数据进行搜索。

  • 使用亚马逊云搜索。有一些已知的限制。我列出了一些我不喜欢的:

    • 文档大小小于 1MB。
    • 在一个字段中最多可以指定 100 个值。
    • 不是开源的。

对于搜索实现之间的一些比较:

于 2012-10-23T09:14:26.447 回答
2

您可以使用带有tsearch2列的搜索表,该列将允许您进行全文搜索以及您需要查询的每一列:例如名称和位置。

如果您的表都继承自同一个模型,那么在搜索表中引用它们会更容易。如果没有,您可以构建一个内容类型表来放置通用外键,这些外键将在您的搜索表中用于引用最终允许检索查询结果的结果行。该表使用触发器填充。这可能是最有效的解决方案,特别是如果您非常了解 SQL(可能是 PL/SQL)。

如果不是这样,我建议你使用Lucene在 Java 中构建你需要的索引,并根据需要进行查询。

于 2012-10-20T04:32:34.537 回答
1

你有很多不同的要求,没有软件能够满足所有这些要求。

  1. 自定义搜索语法
  2. 多实体搜索
  3. 全文搜索
  4. 语义搜索 (?)

让我们来谈谈他们中的每一个。

自定义搜索语法

您需要一个能够根据用户输入构建格式良好的查询的系统。这个系统不仅能做到+metallica -bieber -> text CONTAIN metallica AND text NOT CONTAIN bieber

你的例子并不完全准确。系统如何根据“位置:伦敦”找到“阿森纳”?系统如何根据“位置:伦敦”找到“Neil Christian”?

解决方案:我很确定像 Lucene 这样的系统在搜索查询中支持丰富的语法。但是,它将是框架语法,而不是您自己的。请注意,指定自己的语法很困难;您将需要构建一个词法分析器、解析器和您自己的翻译到您的搜索框架的查询树。

多实体搜索

您需要一次搜索多个实体。这对搜索框架来说没有问题。

但是,您还想定义搜索结构并将其链接回您的实体。这会有点困难,但并非不可能做到。

全文搜索

这也很简单。

语义搜索

高级搜索框架应该支持语义搜索(例如LondonQueen有关,因为它们在某些文本中经常一起出现)。不过,这可能取决于您的训练数据集。

结论

难做的不是继承,也不是全文检索。但是,您应该真正定义数据的匹配方式。搜索系统不是魔术,虽然谷歌可能会这样看。搜索依赖于真正的数学;在进一步讨论之前,您应该在语法上指定这些数学规则。

于 2012-10-23T19:22:59.857 回答
1

我假设您没有使用具有本机全文实现的数据库,所以这是一个穷人的解决方案,但在您使用完整的解决方案(如 Lucene 或任何其他搜索服务建议)之前,它可以让您开始并交付一些东西可能需要更长的学习时间。

您可以简单地安排一个不时运行的进程以从所有这些不同的表中获取所有数据并将它们转储到“索引”表中,您可以在其中执行搜索而无需所有连接。

你可以有一个表,例如:

eventId - int
keywords - nvarchar(max)
location - nvarchar
start_date - datetime
end_date - datetime

这样,您将拥有在一个地方执行搜索所需的一切。对于搜索本身,您可能会在查询中使用 like 运算符获得不错的结果。

不是男人梦寐以求的最佳搜索平台,但您可以在几个小时内完成工作。

于 2012-10-23T11:53:44.153 回答
-1

SQLite 支持全文索引:

http://sqlite.org/fts3.html

于 2012-10-14T12:07:56.427 回答