0

我开始在我的项目中开发方面搜索。作为示例,它应该如何工作,我以 asos.com 为例。作为引擎,我使用 mysql 不进行全文搜索,使用 sphinx 进行全文搜索。为了更快地搜索,我对 db 中的数据进行了非规范化并为此创建了特殊表。

CREATE TABLE `item_search` (
  `id` int(10) unsigned NOT NULL DEFAULT '0',
  `item_id` int(10) unsigned NOT NULL DEFAULT '0',
  `tab` tinyint(3) unsigned NOT NULL,
  `designer_id` smallint(5) unsigned NOT NULL,
  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `price` decimal(18,2) NOT NULL,
  `arm` tinyint(3) unsigned NOT NULL,
  `bridge` tinyint(3) unsigned NOT NULL,
  `lens_width` tinyint(3) unsigned NOT NULL,
  `rating` int(11) unsigned DEFAULT '0',
  `pageviews` int(11) unsigned DEFAULT '0',
  `category_id` int(4) unsigned NOT NULL,
  KEY `index2` (`item_id`,`tab`,`price`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY LIST (tab)
(PARTITION pg VALUES IN (1) ENGINE = InnoDB,
 PARTITION rx VALUES IN (2) ENGINE = InnoDB,
 PARTITION sun VALUES IN (3) ENGINE = InnoDB,
 PARTITION acc VALUES IN (4) ENGINE = InnoDB)

如何在代码中查看。

if (Arr::get($args, 'query')){
  // Get item ids that was found by query
  $args['item_ids'] = Items::findByFullText($args);
}

...//Some code here

if ($item_ids = Arr::get($args, 'item_ids')){
  $where[] = "item_id IN (".implode(',', $item_ids).")";
}

...// Build and execute query and return item_ids

我可以发送多个组中的多个类别进行搜索。

if ($categories = Arr::get($args, 'categories')){
  // group categories by categories group
  $categories = Category::groupCategories($categories);

  foreach ($categories as $group_id => $category_group){
   foreach ($category_group as $category_id){
    $item_ids[$group_id][] = Category::getItemIdsByCategory($category_id);
   }

   // Sum all item ids by this group
   if (sizeof($item_ids[$group_id]) == 1){
    $item_ids_by_group[$group_id] = $item_ids[$group_id][0];
   }else{
    $item_ids_by_group[$group_id] = call_user_func_array('array_merge', $item_ids[$group_id]);
   }
  }

  // Return found item ids by categories
   (sizeof($item_ids_by_group) == 1)
        ? $item_ids_by_group[$group_id]
        : call_user_func_array('array_intersect', $item_ids_by_group);
}

如果为结果启用缓存,这将非常快,只有一个问题在这里没有可能获取像 asos.do 这样的类别。返回类别组的类别 ID 应该是什么逻辑?非常感谢您的任何回复。

4

1 回答 1

1

Mysql 使用 B-TREE 来存储索引,Lucene 上的 Sorl(这是一个功能强大的 Java 库,专门用于搜索内容)使用术语字典和二进制搜索来搜索这些术语。在 Solr 中索引 10 亿个文档只需要不到 1 秒的时间,这与任何 sql 解决方案都比不上。
这是一个很好的教程:http
: //searchhub.org/2009/09/02/faceted-search-with-solr/ 我已经测试了 5 亿份文档,但仍然得到了不到 1 秒的结果,这些确切的结果可以通过在一个简单的谷歌搜索上的类似体验。
另外,我可能会补充一点,由于使用 Mysql 进行分面的开销,它不再使用了。

基本上,今天用作最佳实践的框架是在 Memcache/Solr 和您的主要 Sql 解决方案中编写,然后从 Solr/Memcache 中只读。

这是我曾经为它工作并使用 Solr 作为分面和搜索引擎的 eBay 复制品:http ://www.okazii.ro/

另外,如果您坚持使用 sphinx,请尝试:http ://www.dreamstime.com

另外,看看这个比较:

选择独立的全文搜索服务器:Sphinx 还是 SOLR?

如您所见:Solr 提供了开箱即用的方面支持。Sphinx 中的刻面需要更多的工作。

于 2013-11-14T11:31:12.373 回答