我正在尝试实现超快速搜索,并决定严重依赖缓存来实现这一目标。事件的顺序如下;
1)缓存可以缓存的内容(来自整个数据库,大约3000个项目)
2)执行搜索时,将整个结果集拉出缓存
3)根据搜索条件筛选结果集。为每个搜索结果提供“相关性”分数。
4)通过xml将过滤后的结果发送到数据库以获取无法缓存的位(例如价格)
5)显示最终结果
这一切都在以闪电般的速度发挥作用,但为了实现(3)我给每个结果一个“相关性”分数。这只是每个搜索结果对象的成员整数。我遍历整个结果集并相应地更新这个分数,然后在最后按顺序排序。
我遇到的问题是“相关性”成员将此值保留在搜索范围内。我假设这是因为我正在更新的是对缓存中的搜索结果的引用,而不是新对象,因此更新它也会更新缓存版本。我正在寻找的是一个解决这个问题的简洁解决方案。到目前为止我想出的是;
a)当我得到它时克隆缓存。
b)创建一个单独的字典来存储相关性并在最后匹配它们
我错过了一个非常明显和干净的解决方案,还是应该沿着其中一条路线前进?我正在使用C#和.net。
希望从描述中可以明显看出我所得到的是什么,这里有一些代码;第一个是通过缓存结果的迭代来进行过滤;
private List<QuickSearchResult> performFiltering(string keywords, string regions, List<QuickSearchResult> cachedSearchResults)
{
List<QuickSearchResult> filteredItems = new List<QuickSearchResult>();
string upperedKeywords = keywords.ToUpper();
string[] keywordsArray = upperedKeywords.Split(' ');
string[] regionsArray = regions.Split(',');
foreach (var item in cachedSearchResults)
{
//Check for keywords
if (keywordsArray != null)
{
if (!item.ContainsKeyword(upperedKeywords, keywordsArray))
continue;
}
//Check for regions
if (regionsArray != null)
{
if (!item.IsInRegion(regionsArray))
continue;
}
filteredItems.Add(item);
}
return filteredItems.OrderBy(t=> t.Relevance).Take(_maxSearchResults).ToList<QuickSearchResult>();
}
以下是QuickSearchResult对象的“IsInRegion”方法示例;
public bool IsInRegion(string[] regions)
{
int relevanceScore = 0;
foreach (var region in regions)
{
int parsedRegion = 0;
if (int.TryParse(region, out parsedRegion))
{
foreach (var thisItemsRegion in this.Regions)
{
if (thisItemsRegion.ID == parsedRegion)
relevanceScore += 10;
}
}
}
Relevance += relevanceScore;
return relevanceScore > 0;
}
基本上如果我搜索“伦敦”,我第一次获得“10”分,第二次获得“20”......
答案 0 :(得分:1)
如果使用NetDataContractSerializer序列化缓存中的对象,则可以使用[DataMember]属性来控制序列化的内容和不序列化的内容。例如,您可以将临时计算的相关性值存储在未序列化的字段中。