只缓存对象的一部分

本文关键字:一部分 对象 缓存 | 更新日期: 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]属性来控制什么被序列化,什么不被序列化。例如,您可以将临时计算的相关性值存储在未序列化的字段中。

相关文章: