Lucene.Net ค้นหาชื่อไฟล์/เส้นทาง

ความพยายามครั้งแรกของฉันกับ Lucene.Net

ฉันมีดัชนีที่มีเอกสาร 500 รายการ (html และ pdf) พร้อมบางฟิลด์ เช่น url เนื้อหา ชื่อ

ทุกอย่างทำงานได้ดีเมื่อฉันค้นหาเนื้อหาและ/หรือชื่อเรื่อง
แต่เมื่อฉันค้นหา URL ฉันก็ไม่ได้รับผลลัพธ์

ดังนั้นฉันจึงพบ url เช่น "/tlfdi/epapers/datenschutz2016/files/assets/common/downloads/page0004.pdf" แต่ไม่ใช่ "page0004.pdf"
ด้วย "*" มันไม่ทำงาน

ดัชนีและการค้นหาใช้ WhitespaceAnalyzer ด้วย StandardAnalyzer ฉันได้ผลลัพธ์เป็นศูนย์เมื่อฉันค้นหา "/kontakt/index.aspx"

ค้นหา:

  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;

ใครสามารถช่วยได้บ้าง?


person mMo    schedule 09.12.2016    source แหล่งที่มา
comment
คุณกำลังบอกว่าข้อความค้นหาของคุณคือ page0004.pdf และคุณไม่ได้รับความนิยมใช่หรือไม่   -  person RamblinRose    schedule 31.12.2016


คำตอบ (1)


ราคามาตรฐานของเครื่องวิเคราะห์จะไม่ทำงานตามที่คุณต้องการ แต่คุณจะต้องเขียนโทเค็นและเครื่องวิเคราะห์แบบกำหนดเองแทน

ง่ายมาก! เราเพียงแค่ต้องเริ่มต้นโทเค็นและเครื่องวิเคราะห์

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 ฉันแทนที่ MultiFieldQueryParser ด้วย 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

ขอให้โชคดี!

ปล. ระวังการค้นหาโดยใช้ไวด์การ์ดเพื่อแก้ไขปัญหา ถือเป็นนักฆ่าตัวจริงในดัชนีขนาดใหญ่

person RamblinRose    schedule 30.12.2016