【问题标题】:Lucene.NET 2.9 Custom Filter to add authorisationLucene.NET 2.9 自定义过滤器添加授权
【发布时间】:2013-03-26 08:52:06
【问题描述】:

朋友们,

我是 Lucene 的新手...
我成功地创建了一个索引,添加了字段,我可以搜索等等。

现在,我的数据库中有一个视图,可以告诉哪些用户可以查看哪个文档。这个视图是使用几个复杂的规则创建的,所以我想重用这个视图。因此,我需要在 Lucene 搜索中添加一个过滤器,以删除与查询匹配但用户无权访问的文档。
我现在尝试做的是:
- 将数据库文档 ID 存储在字段中。这是一个 Guid,我将它存储为一个字符串。
- 创建一个自定义过滤器,获取当前用户可以访问的所有文档 id,然后使用 lucene 中的字段进行过滤

我觉得它效率不高...用户可以访问数十万个文档,因此我可能会检索需要过滤的 200 000 个文档 ID。 我想我必须缓存一些东西...
这是我写的代码,但它不起作用:使用过滤器时没有返回任何文档(它应该返回3个文档)

public class LuceneAuthorisationFilter : Filter
{
    public override DocIdSet GetDocIdSet(Lucene.Net.Index.IndexReader reader)
    {
        List<Guid> ids = this.load(); // Load list of ID from database
        OpenBitSet result = new OpenBitSet(reader.MaxDoc);

        int[] docs = new int[1];
        int[] freq = new int[1];

        for (int i = 0; i < ids.Count; i++)
        {
            Lucene.Net.Index.TermDocs termDocs = reader.TermDocs(new Lucene.Net.Index.Term("EmId", ids.ElementAt(i).ToString()));

            int count = termDocs.Read(docs, freq);
            if (count == 1)
            {
                result.FastSet(docs[0]);
            }
        }
        return result;
    }
}

你有什么想法吗?以及如何提高性能?

谢谢

编辑:
上面的代码有效,问题只是 EmId 字段没有被索引。现在我进行了更改,它可以正常工作了。
现在我想知道任何提示以提高性能


第二次编辑以添加反馈

注意:测试环境包含25000个文档,文档访问列表包含50000个id(因为所有文档还没有

索引)

  • 使用上面的自定义过滤器:第一次约 2600 毫秒,下次缓存过滤器时为 2100 毫秒
  • 使用布尔查询过滤器:~4700ms 然后~4000ms

这些性能很差......所以我再次搜索了一个找到的“FieldCacheTermsFilter”过滤器。

  • 使用 FieldCacheTermsFilter:~600ms 然后~60ms

这是可以接受的性能

PS:我还发现了另一个类似的question

【问题讨论】:

    标签: c# search filter lucene lucene.net


    【解决方案1】:

    如果没有给出数字/测量值,谈论表演总是很棘手。

    话虽如此,你的表现如何?您的瓶颈是什么(IO/CPU/等),您是否将其与其他方法进行了比较?

    您真的需要提高性能吗?关于性能改进的讨论不是关于“感觉”,而是围绕基于证据和需要改进的确凿事实。

    现在对于您的Filter,除非我没有从问题中得到什么,否则我不明白为什么您不能使用已内置于 Lucene 中的内容来完成艰苦的工作。

    这是我通常在 Lucene 中处理权限内容的方式,它对于包含数十亿个文档的索引总是很有效。我通常使用具有最小年龄的 LRU 类型缓存来清除缓存中的项目。

    IE:缓存 100 个项目,但如果最近最少使用的时间不超过 15 分钟,则缓存更多。

    如果您尝试这样的事情,如果您将其与您的方法进行比较并返回发布一些性能数据,可能会很有趣。

    免责声明:直接在 SO 的 textarea 中编写的代码,将其视为伪代码而不是已经工作的复制粘贴解决方案:

    // todo: probably some thread safety
    public class AccessFilterFactory
    {
        private static AccessFilterFactory _instance = new AccessFilterFactory();;
        private AccessFilterFactory()
        {
        }
    
        public AccessFilterFactory Instance
        {
            get
            {
                return _instance;
            }
        }
    
        private Cache<int, Filter> someKindaCache = new Cache<int, Filter> ();
    
        // gets a cached filter if already built, if not it creates one
        // caches it and returns it
        public Filter GetFilterForUser(int userId)
        {
            // return from cache if you got it
            if(someKindaCache.Exists(userId))
                return someKindaCache.Get(userId);
    
            // if not, build and cache it
            BooleanQuery filterQuery = new BooleanQuery();
            foreach(string id in ids)
            {
                filterQuery.Add(new TermQuery(new Term("EmId", id)),  BooleanClause.Occur.SHOULD);
            }
            Filter cachingFilter = new CachingWrapperFilter(new QueryWrapperFilter(filterQuery));
            someKindaCache.Put(userId, cachingFilter);
            return cachingFilter;
        }
    
        // removes a new invalid filter from cache (permissions changed)
        public void InvalidateFilter(int userId)
        {
            someKindaCache.Remove(userId);
        }   
    }
    

    【讨论】:

    • 你对表演的“感觉”是正确的。我没有发布任何数字,因为我还没有。而且我也没有“其他方法”来测试更好的性能。我期待您发布的内容:实现相同功能的不同方式,所以我可以尝试选择最好的。以及您从经验中收集到的任何其他提示。例如,使用具有 200 000 个术语的 BooleanQuery 会有效吗?问题是要回答这个问题,我需要编写代码并进行测试。如果有人已经知道这个答案,它可以为我节省很多时间。谢谢你的帖子
    • 我不知道,这需要测试。我目前可以获得的数字是几千(2k-4k 术语)。我的文档被分组到安全类别中,这就是我过滤访问的内容。
    • 只是一些反馈:默认情况下,BooleanQuery 最多接受 1024 个术语。这可以使用静态属性“BooleanQuery.MaxClauseCount”进行更改。但是使用具有 25000 个术语的布尔查询比我在问题中写的过滤器慢 2 倍。在“过滤器”上使用缓存可将搜索时间减少 20%
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    • 2023-03-05
    相关资源
    最近更新 更多