c# – Lucene.NET 2.9自定义过滤器添加授权
作者:互联网
朋友们,
我是Lucene的新手……
我成功创建了一个索引,添加了字段,我可以搜索等工作.
现在,我在我的数据库中有一个视图,告诉哪些用户可以看到哪个文档.此视图是使用几个复杂的规则创建的,因此我想重用该视图.因此,我需要在Lucene搜索中添加一个过滤器,以删除与查询匹配但用户无权访问的文档.
我现在尝试做的是:
– 将db文档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字段.现在我已经改变了它的确有效.
现在我想提出一些提高性能的建议
2ND编辑添加反馈
注意:测试环境包含25 000个文档,文档访问列表包含50 000个ID(因为所有文档尚未存在)
索引)
>使用上面的自定义过滤器:第一次〜2600ms,缓冲过滤器的次数为2100ms
>使用布尔查询过滤器:~4700ms然后~4000ms
这些都是糟糕的表现……所以我再次搜索了一个找到的’FieldCacheTermsFilter’过滤器.
>使用FieldCacheTermsFilter:~600ms然后~60ms
这是可以接受的表现
PS:我还发现了另一个类似的question
解决方法:
当没有给出数字/测量时,谈论表演总是很棘手.
话虽这么说,你在演出方面有什么优势?您的瓶颈(IO / CPU /等)是什么?您是否将其与其他方法进行了比较?
你真的需要提高性能吗?关于性能改进的讨论不是关于“感受”,它们是基于证据和需要改进的事实.
现在为你的过滤器,除非我从问题中得到的东西,我不明白为什么你不能使用已经构建到Lucene的东西来做艰苦的工作.
以下是我通常在Lucene中处理权限的方法,它总是适用于包含数十亿个文档的索引.我通常使用具有最小年龄的LRU类型缓存来清除缓存中的项目.
IE:缓存100个项目,但如果最近最少使用的项目不超过15分钟,则缓存更多.
如果你尝试这样的东西,如果你将它与你的方法进行比较并返回发布一些性能数字可能会很有趣.
免责声明:代码直接写在SO的文本区域中,将其作为伪代码而不是已经工作的复制粘贴解决方案:
// 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);
}
}
标签:c,search,lucene,filter,lucene-net 来源: https://codeday.me/bug/20190629/1327999.html