仅缓存对象的一部分

时间:2011-09-06 15:37:21

标签: c# caching

我正在尝试实现超快速搜索,并决定严重依赖缓存来实现这一目标。事件的顺序如下;

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”......

1 个答案:

答案 0 :(得分:1)

如果使用NetDataContractSerializer序列化缓存中的对象,则可以使用[DataMember]属性来控制序列化的内容和不序列化的内容。例如,您可以将临时计算的相关性值存储在未序列化的字段中。