2016-12-09 2 views
0
는 Lucene.Net와 내 첫 번째 시도는

Lucene.Net 검색/경로

는 내가 가진 500 개 문서 인덱스는 (HTML 및 PDF) URL, 내용, 제목 같은 일부 필드는

모든 잘 작동

내가 URL을 검색 할 때 내용 및/또는 제목
그러나에서 검색 메신저 내가 아무 결과도 얻지 때

그래서 내가 "/tlfdi/epapers/datenschutz2016/files/assets/common/downloads/page0004.pdf 같은 URL을 발견 "아니지만"page0004.pdf "
또한"* "로 작동하지 않습니다.

색인 및 검색은 WhitespaceAnalyzer를 사용합니다.

WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer(); 
    MultiFieldQueryParser parser = new MultiFieldQueryParser(Version.LUCENE_30, 
    new[] { "url", "title", "description", "content", "keywords" }, analyzer); 
    Query query = parseQuery(searchQuery, parser); 
    Lucene.Net.Search.ScoreDoc[] hits = (Lucene.Net.Search.ScoreDoc[])searcher.Search( 
     query, null, hits_limit, Sort.RELEVANCE).ScoreDocs; 

누군가가 도움이 될 수 있습니다 내가

가 검색 "/kontakt/index.aspx"을 검색 할 때 StandardAnalyzer와 내가 제로 결과가 나왔어요?

+0

검색 용어가 "page0004.pdf"이고 조회수가 높지 않습니까? – RamblinRose

답변

2

분석기의 표준 요금은 원하는대로 할 수 없으며 대신 사용자 정의 토크 나이저 및 분석기를 작성해야합니다.

쉽습니다! 우리는 토크 나이저와 분석기를 긁어 내기 만하면됩니다.

UrlTokenizer는 토큰을 생성합니다.

// UrlTokenizer delimits tokens by whitespace, '.' and '/' 
using AttributeSource = Lucene.Net.Util.AttributeSource; 
public class UrlTokenizer : CharTokenizer 
{ 
    public UrlTokenizer(System.IO.TextReader @in) 
     : base(@in) 
    { 
    } 
    public UrlTokenizer(AttributeSource source, System.IO.TextReader @in) 
     : base(source, @in) 
    { 
    } 

    public UrlTokenizer(AttributeFactory factory, System.IO.TextReader @in) 
     : base(factory, @in) 
    { 
    } 
    // 
    // This is where all the magic happens for our UrlTokenizer! 
    // Whitespace, forward slash or a period are a token boundary. 
    // 
    protected override bool IsTokenChar(char c) 
    { 
     return !char.IsWhiteSpace(c) && c != '/' && c != '.'; 
    } 
} 

UrlAnalyzer는 입력 스트림을 소모하는 경우를 구분 검색어 UrlTokenizer 및 LowerCaseFilter를 구현한다.

// Custom Analyzer implementing UrlTokenizer and LowerCaseFilter. 
public sealed class UrlAnalyzer : Analyzer 
{ 
    public override TokenStream TokenStream(System.String fieldName, System.IO.TextReader reader) 
    { 
     // 
     // This is where all the magic happens for UrlAnalyzer! 
     // UrlTokenizer token text are filtered to lowercase text. 
     return new LowerCaseFilter(new UrlTokenizer(reader)); 
    } 
    public override TokenStream ReusableTokenStream(System.String fieldName, System.IO.TextReader reader) 
    { 
     Tokenizer tokenizer = (Tokenizer)PreviousTokenStream; 
     if (tokenizer == null) 
     { 
      tokenizer = new UrlTokenizer(reader); 
      PreviousTokenStream = tokenizer; 
     } 
     else 
      tokenizer.Reset(reader); 
     return tokenizer; 
    } 
} 

다음은 UrlAnalyzer를 시연하는 코드입니다. 나는 MultiPieldQueryParser를 QueryParser로 대체하여 명확하게했다.

// 
// Demonstrate UrlAnalyzer using an in memory index. 
// 
public static void testUrlAnalyzer() 
{  
    string url = @"/tlfdi/epapers/datenschutz2016/files/assets/common/downloads/page0004.pdf"; 
    UrlAnalyzer analyzer = new UrlAnalyzer(); 
    Directory directory = new RAMDirectory(); 
    QueryParser parser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, "url", analyzer); 
    IndexWriter writer = new IndexWriter(directory, analyzer, true, new IndexWriter.MaxFieldLength(2048)); 
    // 
    // index a document. We're only interested in the "url" field of a document. 
    // 
    Document doc = new Document(); 
    Field field = new Field("url", url, Field.Store.NO, Field.Index.ANALYZED); 
    doc.Add(field); 
    writer.AddDocument(doc); 
    writer.Commit(); 
    // 
    // search the index for any documents having 'page004.pdf' in the url field. 
    // 
    string searchText = "url:page0004.pdf"; 
    IndexReader reader = IndexReader.Open(directory, true); 
    IndexSearcher searcher = new IndexSearcher(reader); 
    Query query = parser.Parse(searchText); 
    ScoreDoc[] hits = searcher.Search(query, null, 10, Sort.RELEVANCE).ScoreDocs; 
    if (hits.Length == 0) 
     throw new System.Exception("RamblinRose is fail!"); 
    // 
    // search the index for any documents having the full URL we indexed. 
    // 
    searchText = "url:\"" + url + "\""; 
    query = parser.Parse(searchText); 
    hits = searcher.Search(query, null, 10, Sort.RELEVANCE).ScoreDocs; 
    if (hits.Length == 0) 
     throw new System.Exception("RamblinRose is fail!"); 
} 

Lucene.net은 좋은 재료입니다. 이 코드가 Lucene 분석에 대한 이해를 높이기를 바랍니다.

행운을 빈다.

p.s. 문제를 해결하기 위해 와일드 카드 검색을주의해야합니다. 큰 인덱스에서 실제 킬러입니다.