只缓存对象的一部分
本文关键字:一部分 对象 缓存 | 更新日期: 2023-09-27 18:07:37
我试图实现超快速的搜索,并决定严重依赖缓存来实现这一目标。事件发生的顺序如下:
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;
}
基本上,如果我搜索"london",我第一次得到的分数是"10",第二次得到的分数是"20"。
如果你使用NetDataContractSerializer来序列化缓存中的对象,你可以使用[DataMember]属性来控制什么被序列化,什么不被序列化。例如,您可以将临时计算的相关性值存储在未序列化的字段中。