English 中文(简体)
Lucene.net: 记录和使用过滤器限制结果
原标题:Lucene.net: Querying and using a filter to limit results

如同往常一样,我谈谈大脑力,大脑力是用来帮助解决卢塞恩问题的斯纳克里用户基础。 NET 问题 我与大家一道工作。 首先,在Lucene和Lucene问题上,我是完全的。 通过网络,并通过在线使用分散的辅导和密码信使,我共同赞同我的情景下的解决办法。

我有以下结构的指数:

---------------------------------------------------------
| id  |    date    | security |           text          |
---------------------------------------------------------
|  1  | 2011-01-01 | -1-12-4- | some analyzed text here |
---------------------------------------------------------
|  2  | 2011-01-01 |  -11-3-  | some analyzed text here |
---------------------------------------------------------
|  3  | 2011-01-01 |    -1-   | some analyzed text here |
---------------------------------------------------------

我需要能够询问案文领域,但把结果限制在具有具体作用使用者身上。 页: 1

我为达到这一目的(在多次前往谷歌之后),即使用“安全领域”和卢塞尼过滤器,以限制以下所列结果:

class SecurityFilter : Lucene.Net.Search.Filter
{
    public override System.Collections.BitArray Bits(Lucene.Net.Index.IndexReader indexReader)
    {
        BitArray bitarray = new BitArray(indexReader.MaxDoc());

        for (int i = 0; i < bitarray.Length; i++)
        {
            if (indexReader.Document(i).Get("security").Contains("-1-"))
            {
                bitarray.Set(i, true);
            }
        }

        return bitarray;
    }
}

......

Lucene.Net.Search.Sort sort = new Lucene.Net.Search.Sort(new Lucene.Net.Search.SortField("date", true));
Lucene.Net.Analysis.Standard.StandardAnalyzer analyzer = new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29);
Lucene.Net.Search.IndexSearcher searcher = new Lucene.Net.Search.IndexSearcher(Lucene.Net.Store.FSDirectory.Open(indexDirectory), true);
Lucene.Net.QueryParsers.QueryParser parser = new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_29, "text", analyzer);
Lucene.Net.Search.Query query = parser.Parse("some search phrase");
SecurityFilter filter = new SecurityFilter();
Lucene.Net.Search.Hits hits = searcher.Search(query, filter, sort);

这一工作按预期进行,只有交回文件的时间为1和3。 问题是,在很大程度上,这一进程进展缓慢。

最后,我的问题...... 是否有任何人ti想如何加快解决,或找到比我在这里提出的解决办法更为有效的替代解决办法?

最佳回答

我用一个简单的例子改变了我的回答,解释我先前回答中的含义。

我迅速这样做,并坚决尊重最佳做法,但应该给你这个想法。

请注意,安全领域需要标注,以便其中的每一份识别资料都单独标示,例如,使用 rel=“nofollow”>,白天航天飞机/天线。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net.Search;
using Lucene.Net.Documents;
using Lucene.Net.Index;
using Lucene.Net.Analysis.Standard;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        public class RoleFilterCache
        {
            static public Dictionary<string, Filter> Cache = new Dictionary<string,Filter>();

            static public Filter Get(string role)
            {
                Filter cached = null;
                if (!Cache.TryGetValue(role, out cached))
                {
                    return null;
                }
                return cached;
            }

            static public void Put(string role, Filter filter)
            {
                if (role != null)
                {
                    Cache[role] = filter;
                }
            }
        }

        public class User
        {
            public string Username;
            public List<string> Roles;
        }

        public static Filter GetFilterForUser(User u)
        {
            BooleanFilter userFilter = new BooleanFilter();
            foreach (string rolename in u.Roles)
            {   
                // call GetFilterForRole and add to the BooleanFilter
                userFilter.Add(
                    new BooleanFilterClause(GetFilterForRole(rolename), BooleanClause.Occur.SHOULD)
                );
            }
            return userFilter;
        }

        public static Filter GetFilterForRole(string role)
        {
            Filter roleFilter = RoleFilterCache.Get(role);
            if (roleFilter == null)
            {
                roleFilter =
                    // the caching wrapper filter makes it cache the BitSet per segmentreader
                    new CachingWrapperFilter(
                        // builds the filter from the index and not from iterating
                        // stored doc content which is much faster
                        new QueryWrapperFilter(
                            new TermQuery(
                                new Term("security", role)
                            )
                        )
                );
                // put in cache
                RoleFilterCache.Put(role, roleFilter);
            }
            return roleFilter;
        }


        static void Main(string[] args)
        {
            IndexWriter iw = new IndexWriter(new FileInfo("C:\example\"), new StandardAnalyzer(), true);
            Document d = new Document();

            Field aField = new Field("content", "", Field.Store.YES, Field.Index.ANALYZED);
            Field securityField = new Field("security", "", Field.Store.NO, Field.Index.ANALYZED);

            d.Add(aField);
            d.Add(securityField);

            aField.SetValue("Only one can see.");
            securityField.SetValue("1");
            iw.AddDocument(d);
            aField.SetValue("One and two can see.");
            securityField.SetValue("1 2");
            iw.AddDocument(d);
            aField.SetValue("One and two can see.");
            securityField.SetValue("1 2");
            iw.AddDocument(d);
            aField.SetValue("Only two can see.");
            securityField.SetValue("2");
            iw.AddDocument(d);

            iw.Close();

            User userone = new User()
            {
                Username = "User one",
                Roles = new List<string>()
            };
            userone.Roles.Add("1");
            User usertwo = new User()
            {
                Username = "User two",
                Roles = new List<string>()
            };
            usertwo.Roles.Add("2");
            User userthree = new User()
            {
                Username = "User three",
                Roles = new List<string>()
            };
            userthree.Roles.Add("1");
            userthree.Roles.Add("2");

            PhraseQuery phraseQuery = new PhraseQuery();
            phraseQuery.Add(new Term("content", "can"));
            phraseQuery.Add(new Term("content", "see"));

            IndexSearcher searcher = new IndexSearcher("C:\example\", true);

            Filter securityFilter = GetFilterForUser(userone);
            TopDocs results = searcher.Search(phraseQuery, securityFilter,25);
            Console.WriteLine("User One Results:");
            foreach (var aResult in results.ScoreDocs)
            {
                Console.WriteLine(
                    searcher.Doc(aResult.doc).
                    Get("content")
                );
            }
            Console.WriteLine("

");

            securityFilter = GetFilterForUser(usertwo);
            results = searcher.Search(phraseQuery, securityFilter, 25);
            Console.WriteLine("User two Results:");
            foreach (var aResult in results.ScoreDocs)
            {
                Console.WriteLine(
                    searcher.Doc(aResult.doc).
                    Get("content")
                );
            }
            Console.WriteLine("

");

            securityFilter = GetFilterForUser(userthree);
            results = searcher.Search(phraseQuery, securityFilter, 25);
            Console.WriteLine("User three Results (should see everything):");
            foreach (var aResult in results.ScoreDocs)
            {
                Console.WriteLine(
                    searcher.Doc(aResult.doc).
                    Get("content")
                );
            }
            Console.WriteLine("

");
            Console.ReadKey();
        }
    }
}
问题回答

If you index your security field as analyzed (such that it splits your security string as 1 12 4 ...)

you can create a filter like this

Filter filter = new QueryFilter(new TermQuery(new Term("security ", "1")));

f或m a query like some text +security:1





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签