我开始在我的项目中开发方面搜索。作为示例它应该如何工作我拿了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应该是什么逻辑?非常感谢您的回应。
答案 0 :(得分:1)
Mysql使用B-TREE来存储索引,Lucene上的Sorl(这是一个功能强大的Java库,特别是用于搜索内容)使用术语词典和二进制搜索来表示这些术语。在Solr索引十亿个文档,花费不到1秒,用任何sql解决方案打败它。
这是一个很好的教程: http://searchhub.org/2009/09/02/faceted-search-with-solr/
我已经测试了500万份文件并且仍然得到不到1秒的结果,这些确切的结果可以通过简单的谷歌搜索的类似经验来证明。
另外,我可以补充说,由于使用Mysql进行分面的开销,它已不再使用了。
基本上,今天作为最佳实践使用的框架是在Memcache / Solr和主Sql解决方案中编写,然后只从Solr / Memcache中读取。
这是我曾经工作的eBay副本,并使用Solr作为它的分面和搜索引擎:http://www.okazii.ro/
另外,如果你坚持使用狮身人面像,请尝试:http://www.dreamstime.com
另外,看看这个比较:
Choosing a stand-alone full-text search server: Sphinx or SOLR?
正如您所看到的:Solr带有开箱即用的小平面支撑。面对狮身人面像需要更多的工作。