Sitecore.NET 6.6.0(rev.130404)
我们的生产网站搜索量非常大,我们的Lucene索引全天都在大量查询。这相当于在Lucene查询处理上花费了大量的CPU功率。是否存在将Lucene索引和查询卸载到其他计算机的行业惯例?或者是否有任何可用于提高Lucene查询性能的硬件机制?
(我们最常用的Lucene索引包含少于10,000个条目)
更新(更多信息):
虽然我们的索引包含的内容少于10,000,但CPU使用率是否会由并行执行的大量Lucene查询引起?我们有一个非常复杂的分面搜索。最初,当用户尝试各种搜索条件时,我们会在所有搜索选项旁边显示结果计数细分(每次搜索请求会产生50-60个计数查询)。这导致高流量时CPU使用率达到90-95%。当我们删除计数时,CPU稳定在20-30%左右。
以下是我们用于查询的两种方法:
public static Document[] GetLuceneDocuments(ACIndex acIndex, Query query, Sort sort = null, int maxResults = 999, bool trackScores = false, bool fillFields = true)
{
Index index = SearchManager.GetIndex(GetIndexName(acIndex));
if (sort == null)
{
sort = new Sort(new SortField(null, SortField.SCORE));
}
using (IndexSearchContext searchContext = index.CreateSearchContext())
{
Lucene.Net.Search.IndexSearcher searcher = searchContext.Searcher;
TopFieldCollector collector = TopFieldCollector.create(sort, maxResults, fillFields, trackScores, false, false);
searcher.Search(query, collector);
TopDocs topdocs = collector.TopDocs();
Document[] documents = new Document[topdocs.ScoreDocs.Length];
for (int i = 0; i < topdocs.ScoreDocs.Length; i++)
{
documents[i] = searcher.Doc(topdocs.ScoreDocs[i].doc);
}
return documents;
}
}
public static int GetSearchResultCount(ACIndex acIndex, Query query)
{
Index index = SearchManager.GetIndex(GetIndexName(acIndex));
using (IndexSearchContext searchContext = index.CreateSearchContext())
{
Lucene.Net.Search.IndexSearcher searcher = searchContext.Searcher;
TopScoreDocCollector collector = TopScoreDocCollector.create(1, false);
searcher.Search(query, collector);
return collector.GetTotalHits();
}
}
答案 0 :(得分:2)
您应该考虑为搜索实施Solr。虽然不是这方面的专家,但Solr基于Lucene(使转换变得更容易)并运行中央服务器或服务器,处理您的所有搜索要求。
在Sitecore 7之前的版本中,Solr在本地不受官方支持 - 但我已经开发了许多使用Solr的Sitecore 6解决方案。
本文应该为您提供一个良好的开端:How to implement Solr into Sitecore
就行业流程而言,使用Sitecore,Solr是解决此特定问题的解决方案。然而,根据您的解决方案实施情况,可能需要做一些工作才能起床和继续。
答案 1 :(得分:0)
您可以在www.alpha-solutions.dk/sitecore-search-solution上查看Siter 6上的Solr方法。 注意:我隶属于Alpha Solutions
答案 2 :(得分:0)
你的索引很小,我知道有建议你重新解析整个解决方案,不过,我建议我过去做过的一些对我有用的东西,并且不要求你配置另一台服务器或安装另一个索引像弹性或SOLR这样的工具。
首先,将字段存储在您所面对的索引中,如下所示(在配置中或使用自定义搜寻器):
创建一个表示结果的类
public class MyThing
{
public string Manufacturer { get; set; }
public string Size { get; set; }
public int Year { get; set; }
public MyThing(Document doc)
{
Manufacturer = doc.GetField("Manufacturer").Value;
Size = doc.GetField("Size").Value;
Year = int.Parse(doc.GetField("Year").Value);
}
}
然后将您的主要搜索结果命中,实例化您的轻量级POCO,并对其进行计数。 Voila,1个查询!
int countForSomething = results.Count(result =&gt; result.Size ==“XL”);
注意:我有点把这段代码写下来,但你明白了。我在Lucene的索引上使用了这个过程,在Sitecore中的结果高达700K +没有太多问题。祝你好运先生!
答案 3 :(得分:0)
啊!刚刚解决了分面搜索和CPU使用问题。这是一些边界线黑魔法编码和一些非常有创意的缓存。
我们找到了一种方法来实现Solr对Lucene的分面查询,男孩和男孩的结果非常快。
简短版本:
构建一个保存在字典上的静态类。键:单个过滤器的唯一表示,值:由Lucene QueryFilter对象生成的BitArray。
var queryFilter = new QueryFilter(filterBooleanQuery); var bits = queryFilter.Bits(indexReader); result [filter.ID.ToString()] = bits
在后台异步定期构建此字典。我的大约80k文档的索引只需要大约15秒的时间来构建,但这足以让很多用户生气,所以以非阻塞的方式做这件事是至关重要的。
使用按位逻辑查询此字典,以查找表示您正在查找的匹配项的结果BitArray。
var combo = facetDictionary [thisFilter.ID.ToString()] 。而(facetDictionary [selectedFilter.ID.ToString()]);
长版: http://www.devatwork.nl/articles/lucenenet/faceted-search-and-drill-down-lucenenet/
现在,我们的实现只是为了获得这些结果集的基数,但理论上你也可以使用这些位数组来获取索引中的实际文档。
祝你好运!答案 4 :(得分:0)
升级到sitecore 7会为您提供开箱即用的方面。在一个漂亮的LINQ API中抽象,让你从Lucene和SOLR切换(其他人,比如ElasticSearch即将推出)......