3

我目前正在开发用于搜索功能的索引器。索引器将处理来自“字段”的数据。字段看起来像:

  Field_id   Field_type   Field_name   Field_Data
- 101        text         Name         Intel i7
- 102        integer      Cores        4 physical, 4 virtual
- 103        select       Vendor       Intel
- 104        multitext    Description  The i7 is intel's next gen range of cpus.

索引器将生成以下结果/索引:

  Keyword    Occurrences
- intel      101, 103, 104
- i7         101, 104
- physical   102
- virtual    102
- next       104
- gen        104
- range      104
- cpus       104   (*)
- cpu        104   (*)

所以看起来一切都很好,但是,我想解决一些问题:

  • 过滤掉常用词(您可能注意到,列表中缺少“the”、“is”、“of”和“intel's”)
  • 关于“cpus”(复数与单数),最好同时使用特定类型(单数或复数)还是精确(即“cpus”与“cpu”不同)?
  • 继续上一项,我如何确定复数(不同的口味:测试=>测试鱼=>鱼和叶子=>叶子)
  • 我目前正在使用 MySql,我非常关心性能问题;我们有 500 多个类别,我们甚至没有启动该网站
  • 假设我想使用搜索词“vendor:intel”,其中vendor指定字段名称(field_name),您认为对sql server会产生巨大影响吗?
  • 搜索限制;我根本不喜欢这个,但这是有可能的,如果您知道任何解决方法,请让自己听到!
  • 还有其他问题我可能忘记了,如果你发现任何问题,欢迎你对我大喊大叫;-)
  • 我不需要搜索引擎抓取链接,其实我特别希望它不抓取链接

(顺便说一句,我并不偏向于英特尔,只是碰巧我拥有一台基于 i7 的电脑 ;-))

4

7 回答 7

3

从这里获取停用词(非关键字)列表,该人甚至为您将它们格式化为 php。 http://armandbrahaj.blog.al/2009/04/14/list-of-english-stop-words/

然后只需对要索引的字符串执行 preg_replace 即可。

我过去所做的是使用正则表达式删除像“s”、“ed”等后缀,并在搜索字符串上使用相同的正则表达式。但这并不理想。这是一个只有 200 页的基本网站。

如果您担心性能,您可能需要考虑使用像 Lucine (solr) 这样的搜索引擎而不是数据库。这将使索引更容易。你不想在这里重新发明轮子。

于 2010-07-23T07:16:48.303 回答
1

我衷心建议您看看 Solr。它是一个基于 Java 的自包含搜索和索引系统,可能比 PHP 解决方案有更多的好处。

于 2010-07-23T09:35:51.947 回答
1

过滤掉常用词(您可能注意到,列表中缺少“the”、“is”、“of”和“intel's”)

查找(或创建)常用词列表并过滤用户输入。

关于“cpus”(复数与单数),最好同时使用特定类型(单数或复数)还是精确(即“cpus”与“cpu”不同)?

依靠。如果这不是一个很大的负担,我会搜索两者;或者如果可能,使用 LIKE 子句的单数形式。

继续上一项,我如何确定复数(不同的口味:测试=>测试鱼=>鱼和叶子=>叶子)

创建一个 Inflector 方法或类。即:Inflect::plural('fish')给你'fish'。可能有这样的英语课程,查一下。

我目前正在使用 MySql,我非常关心性能问题;我们有 500 多个类别,我们甚至没有启动该网站

拥有良好的架构和代码设计会有所帮助,但我真的不能给你太多建议。

假设我想使用搜索词“vendor:intel”,其中vendor指定字段名称(field_name),您认为对sql server会产生巨大影响吗?

这真的很有帮助,因为您要查找的是单列而不是多列。请注意过滤用户输入和/或只允许查找特定列。

搜索限制;我根本不喜欢这个,但这是有可能的,如果您知道任何解决方法,请让自己听到!

这里没有多少选择。为了在此处和性能方面有所帮助,您应该考虑使用某种缓存。

于 2010-07-23T12:31:23.767 回答
1

这是对您最初的问题和您后来的回答/问题的回应。

我之前使用过Sphinx搜索引擎(很久以前,所以我有点生疏),发现它非常好,即使文档有时有点缺乏​​。

我确信还有其他方法可以做到这一点,无论是使用您自己的自定义代码,还是使用其他搜索引擎——Sphinx 恰好是我使用过的那个。我并不是说它会按照你想要的方式做你想做的一切,但我有理由相信它会很容易地完成大部分工作,而且比单独用 PHP/MySQL 编写的任何东西都要快得多。

我建议在深入研究Sphinx 文档之前阅读使用 PHP 构建自定义搜索引擎。如果您在阅读后认为它不合适,那就足够了。

在回答您的具体问题时,我整理了文档中的一些链接以及一些相关的引用:

过滤掉常用词(您可能注意到,列表中缺少“the”、“is”、“of”和“intel's”)

11.2.8。停用词

停用词是不会被索引的词。通常,您会将最常用的词放在停用词列表中,因为它们不会为搜索结果增加太多价值,但会消耗大量资源来处理。

关于“cpus”(复数与单数),最好同时使用特定类型(单数或复数)还是精确(即“cpus”与“cpu”不同)?

11.2.9。词形

在通过 charset_table 规则对传入文本进行标记后应用单词形式。它们本质上让你用另一个词替换一个词。通常,这将用于将不同的单词形式带入一个范式(例如,将所有变体如“walks”、“walked”、“walking”规范化为范式“walk”)。它还可以用于实现词干异常,因为词干不适用于表单列表中的单词。

继续上一项,我如何确定复数(不同的口味:测试=>测试鱼=>鱼和叶子=>叶子)

Sphinx 支持Porter 词干算法

Porter 词干算法(或“Porter stemmer”)是一种从英语单词中去除常见的形态和屈折词尾的过程。它的主要用途是作为通常在设置信息检索系统时完成的术语规范化过程的一部分。

假设我想使用搜索词“vendor:intel”,其中vendor指定字段名称(field_name),您认为对sql server会产生巨大影响吗?

3.2. 属性

属性的一个很好的例子是论坛帖子表。假设只有标题和内容字段需要全文搜索 - 但有时还需要将搜索限制为某个作者或子论坛(即仅搜索具有某些特定 author_id 或 forum_id 值的行SQL 表中的列);或按 post_date 列对匹配项进行排序;或按 post_date 的月份对匹配的帖子进行分组并计算每组匹配计数。

这可以通过将所有提到的列(不包括标题和内容,它们是全文字段)指定为属性、索引它们,然后使用 API 调用来设置过滤、排序和分组来实现。

您也可以使用5.3。扩展查询语法以搜索特定字段(而不是按属性过滤结果):

字段搜索运算符:@vendor intel

搜索引擎如何索引一组字段并将找到的短语/关键字/等与特定字段 id 绑定?

8.6.1. 询问

成功时,Query() 返回一个结果集,其中包含一些找到的匹配项(根据 SetLimits() 的要求)和附加的一般查询统计信息。> 结果集是具有以下键和值的散列(特定于 PHP;其他语言可能使用其他结构而不是散列):

“matches”:
将找到的文档 ID 映射到另一个包含文档权重和属性值的小散列的散列(如果启用了 SetArrayResult(),则为类似的小散列数组)。

“total”:
此查询在服务器上检索到的匹配总数(即到服务器端结果集)。您可以使用当前查询设置从服务器检索此查询文本的最多匹配数量。

“total_found”:
索引中匹配文档的总数(在服务器上找到并处理)。

“words”:
将查询关键字(大小写折叠、词干提取和其他处理)映射到具有每个关键字统计信息(“docs”、“hits”)的小散列的散列。

“error”:
searchd报告的查询错误信息(字符串,可读)。如果没有错误,则为空。

“warning”:
查询 searchd 上报的警告信息(字符串,可读)。如果没有警告,则为空。

另请参阅Build a custom search engine with PHP中的清单 11清单 13

于 2010-07-23T15:15:15.623 回答
0

搜索很难实现。如果您是新手,建议您使用软件包。

您是否考虑过http://framework.zend.com/manual/en/zend.search.lucene.html

于 2010-07-23T08:01:46.940 回答
0

由于许多人建议使用现有的包,(而且我想让你更难,而不是仅仅建议一个包;-)),让我们假设我会使用这样的包(在这个答案线程中)。

搜索引擎如何索引一组字段并将找到的短语/关键字/等与特定字段 id 绑定?这不是我想要回答的问题,至少不是直接回答。我的问题是,让搜索引擎按我的意愿工作有多容易?鉴于我的上述要求,这甚至可能/可行吗?

从个人经验来看,我宁愿浪费一些时间来调整我的系统,而不是修复别人的代码,我必须先浪费更多的时间来理解。称我为保守派,但我很少坚持别人的代码/程序,当我这样做时,那是因为绝望的情况——我通常最终会以某种方式为所说的项目做出贡献。

于 2010-07-23T08:29:28.267 回答
0

在php/ir上有一个 Brill Part of Speech 标记器的 PHP 实现。这可能会提供一个框架来识别那些应该被丢弃的单词和那些你想要索引的单词,同时它还可以识别复数(和词根单数)。它并不完美,虽然是处理技术术语的自定义词典,但它可能对解决您的前三个问题很有用。

于 2010-07-23T10:11:33.823 回答