zoukankan      html  css  js  c++  java
  • Lucene.NET 若干知识点&&疑难杂症以及解决

    1.new Field("id", package.Id.ToString(), Field.Store.YES, Field.Index.TOKENIZED)

      几个字段解析,“id”:索引字段的KEY,package.Id.ToString(),索引的值, Field.Store.YES,是否将值存入,如果是NO,该字段值无法提取出,Field.Index.TOKENIZED这个意思是是否建立索引,如果建立索引是否参与分词,TOKENIZED是参与分词,UN_TOKENIZED是不参与分词,直接全词索引,如果不希望改字段被分词最好选用这个属性。

    2.如何判断所以是否建立成功,最基本的方法,查看索引创建时的索引数据文件,800多条数据几百K总是要有的。

    3. 索引建立成功,查询时最简单的某字段TERM查询查询不出该结果,怎么办?

      由于LUCENE查询时全词匹配,如果某字段按原值(如Name:)查询没有结果,首先要想到是否该字段被分词解析开了,比如:中华人民共和国,用标准分词器就会拆分成:中 华 人 民 共 盒国 一个字一个索引,你要按照中华查就或者原词查都查不到。这里有2个办法,1:在创建索引时将Field.Index.UN_TOKENIZED这样改字段就不参与分词,2:如果你整个需求没有太多分词的要求,或者分词的要求很明确有规律(比如按‘,’按‘ ’)分词,那可以自己重写一个分词器:

    public class EsayTooTokenizer : CharTokenizer
        {
            public EsayTooTokenizer(TextReader reader)
                : base(reader)
            {
            }
    
            //单纯按照“,” 空格 分词
            protected override bool IsTokenChar(char c)
            {
                return c == ',' || c == ' ' ? false : true;
            }
        }
    
        public class EsayTooAnalyzer : Analyzer
        {
            public override TokenStream TokenStream(string fieldName, System.IO.TextReader reader)
            {
                return new EsayTooTokenizer(reader);
            }
        }
    

      以上就是单纯只按照逗号跟空格分词。

    如果不知道分词结果,可以借鉴一下我写的分词器测试方法:

           public static void ShowAnalyzerResult(Analyzer analyzer, String s) 
            { 
    
                StringReader reader = new StringReader(s); 
                TokenStream ts = analyzer.TokenStream(s, reader); 
    
                var t = ts.Next(); 
                while (t != null) {
                    Console.WriteLine(t.TermText() + " "); 
                t = ts.Next(); 
                }
                Console.WriteLine();
            } 
    
    //调用方法
                Analyzer analyzer1 = new EsayTooAnalyzer();
                ShowAnalyzerResult(analyzer1, "大灯 (左)432");
                ShowAnalyzerResult(analyzer1, "A43243 24321");
                ShowAnalyzerResult(analyzer1, "这个事,情我怎么看啊");

     4.索引更新问题,这个是我在开发时候碰到的,使用IndexWriter新增索引数据,调试的时候发现初始化时候索引正常添加,但是每次新增索引数据时就会复制一份.cfs文件然后对该文件增加索引,源文件始终是不动,再试了N多方法之后发现原来是我查询的IndexSearcher采用了一个静态的对象,只要查询过数据之后这个对象就会占用.cfs文件,这时在做更新就会新增一个缓存CFS文件,导致缓存查询失败。 解决方案:每次查询时候新建IndexSearcher,并在查询语句之后把它CLOSE();

    5.IndexReader.DeleteDocuments(Term) 相关POST

    2010-02-19 23:30

    Lucene删除索引DeleteDocuments的注意事项

    Lucene在删除索引时,经常会出现代码成功执行,但索引并未正直删除的现象,总结一下,要注意以下因素:

    1.在创建Term时,注意Term的key一定要是以"词"为单位,否则删除不成功,例如:添加索引时,如果把"d:\doc\id.txt"当作要索引的字符串索引过了,那么在删除时,如果直接把"d:\doc\id.txt"作为查询的key来创建Term是无效的,应该用Id.txt(但这样会把所有文件名为Id.txt的都删除,所以官方建议最好用一个能唯一标识的关键字来删除,比如产品编号,新闻编号等(我的猜想:每个document都加入一个id字段作为唯一标识(可用系统当前时间值作为id的值),每当要删除包含某关键字的文档索引时,先将这些文档搜索出来,然后获取它们的id值,传给一个List,然后再用List结合id字段来删除那些文档的索引......不过这个方法的效率可能会低了一点,因为每个文档都要搜两遍);

    2.要删除的“词”,在创建索引时,一定要是Tokened过的,否则也不成功;

    3.IndexReader,IndexModifer,IndexWriter都提供了DeleteDocuements方法,但建议用 IndexModifer来操作,原因是IndexModifer内部做了很多线程安全处理;

    4.删除完成后,一定要调用相应的Close方法,否则并未真正从索引中删除。

  • 相关阅读:
    TCP 窗口缩放、时间戳和 SACK
    对微前端的11个错误认识
    终于解决了使用Python装饰器的一个痛点
    go使用mongo
    获取鼠标当前元素
    console控制台屏蔽console
    httpx使用HTTP/2
    go解析未知结构的json
    python字典转对象
    .::Best Musica Paradisa::.
  • 原文地址:https://www.cnblogs.com/vinnie520/p/2559033.html
Copyright © 2011-2022 走看看