Martin Zagora - News, RSS, lucene

    Table of contents
    No headers

     

    Ciel projektu:

    Vytvoriť aplikáciu na čítanie RSS feed-ov a ich indexovanie + vyhľadávanie pomocou lucene. V súčasnosti máme veľké množstvo RSS čítačiek ktoré umožňujú aj vyhľadávanie - motiváciou projektu je skôr osvojenie si prácu s knižnicou na vyhľadávanie informácií lucene, než vytvorenie bezchybnej RSS čítačky.

    Existujúci softvér na danú tému:

    RSS čítačiek existuje veľké množstvo. Môžme ich deliť na webové aplikácie a desktopové aplikácie. Výhodou webových je, že sú stále aktívne a často sťahujú obsah, teda ak sme dlhšiu dobu od počítača (a ten je vypnutý) tak sa nám novinky uchovajú. V prípade desktopových čítačiek hrozí, že ak aplikácia nebude zapnutá určitú dobu, uniknú nám informácie o niektorých článkoch (záleží od frekvencie pribúdania nových článkov a počtu poskytovaných dokumentov na jednom RSS kanáli).

    RSS:

    Jedná sa o zdroj informácií v podobe štandardizovaného XML dokumentu, ktorý poskytujú stránky k odberu noviniek bez nutnosti navštíviť web. Väčšinou sa vyskytuje na stránkach kde sa často mení obsah (spravodajské servery a pod.). V projekte bude RSS použité ako zdroj informácií - dokumentov. Viac o RSS napr TU.

    Lucene:

    Je to v originále Java knižnica na získavanie informácií. Bola portovaná do pomerne veľkého počtu programovacích jazykov ako Object Pascal (Delphi), Perl, C#, C++, Python, Ruby alebo PHP. Lucene je vhodná na indexovanie a vyhľadávanie prakticky v akomkoľvek texte a je využívaná hlavne na implementáciu vyhľadávania na internetových stránkach a portáloch.

    Domovská stránka Lucene. 

    Popis a priebeh riešenia:

    Pôvodne som chcel realizovať projekt ako web aplikáciu pomocou Java Server Pages avšak problematické debugovanie a development na tejto platforme spôsobil, že som po pár hodinách skušania od tohto nápadu upustil.

    Aplikácia je realizovaná ako desktopová RSS čítačka v Jave - Swing. Umožnuje otvorenie prakticky akéhokoľvek RSS feedu z internetu. Pri realizácii sa bolo nutné obozmnámiť nielen s knižnicou lucene ale aj s niektorými java knižnicami, hlavne na realizáciu GUI aplikácie. Pri pracovaní s lucene bola užitočná jej veľká rozšírenosť a veľké množstvo tutorialov na internete.

    Kľúčové miesta projektu:

    1. Načítanie RSS dokumentov (sample ukazuje zistenie počtu itemov v RSS)
      URL url = new URL(strUrl);
      URLConnection conn = url.openConnection();
      
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
      org.w3c.dom.Document d = documentBuilder.parse(conn.getInputStream());
      
      XPath xPath = XPathFactory.newInstance().newXPath();
      Double count = (Double) xPath.evaluate("count(/rss/channel/item)", 
                                              d, PathConstants.NUMBER);
      resText += "url: " + strUrl + "\r\n    items parsed: " + count.intValue() + "\r\n";
      
      
    2. Mapovanie RSS dokumentov do Java objektu RSSItem, nazvy premenných zodpovedajú názvom značiek v RSS XML dokumente
      public class RSSItem
      {
      	private String source;
      	private String sourceUrl;
      	private String title;
      	private String link;
      	private String pubDate;
      	private String description;
      ...
      }
      
      
    3. Indexovanie dokumentov v lucene je veľmi jednoduché. Vytvárame dokument ktorý delíme na určité polia pomocou ktorých môžeme potom vyhľadávať. V mojom projekte som vytvoril špeciálne pole menom "content" ktoré v sebe zahŕňa nadpis aj text RSS dokumentu a pri vyhľadávaní v tomto poli hľadáme ako keby v dvoch poliach naraz (title a description).
      IndexWriter indexWriter = new IndexWriter("index",
      		new StandardAnalyzer(), true,
      		IndexWriter.MaxFieldLength.UNLIMITED);
      Iterator<rssitem/> it = this.rssItems.iterator();
      while (it.hasNext())
      {
      	RSSItem item = it.next();
      	Document doc = new Document();
      	doc.add(new Field("source", item.getSource(), Field.Store.YES,
      			Field.Index.NOT_ANALYZED));
      	doc.add(new Field("sourceUrl", item.getSourceUrl(),
      			Field.Store.YES, Field.Index.NOT_ANALYZED));
      	doc.add(new Field("title", item.getTitle(), Field.Store.YES,
      			Field.Index.ANALYZED));
      	doc.add(new Field("link", item.getLink(), Field.Store.YES,
      			Field.Index.NOT_ANALYZED));
      	doc.add(new Field("pubDate", item.getPubDate(),
      			Field.Store.YES, Field.Index.NO));
      	doc.add(new Field("description", item.getDescription(),
      			Field.Store.YES, Field.Index.ANALYZED));
      
      	doc.add(new Field("content", item.getTitle() + " "
      			+ item.getDescription(), Field.Store.NO,
      			Field.Index.ANALYZED));
      
      	indexWriter.addDocument(doc);
      }
      indexWriter.close();
      
    4. Vyhľadávanie je tiež realizované jednoduchým dotazom. Lucene automaticky z dotazovaného query parsuje znaky ako ? či * a tým nie je nutná žiadna ďalšia modifikácia vyhľadávania. Napr. pri napísaní eur* vám lucene vyhľadá dokumenty ktoré obsahujú slovo začínajúce na eur.
      Analyzer analyzer = new StandardAnalyzer();
      IndexSearcher is = new IndexSearcher("index");
      QueryParser parser = new QueryParser("content", analyzer);
      Query query = parser.parse(queryString);
      TopDocCollector collector = new TopDocCollector(10);
      is.search(query, collector);
      
      ScoreDoc[] hits = collector.topDocs().scoreDocs;
      for (int i = 0; i < hits.length; i++)
      {
      	int docId = hits[i].doc;
      	Document d = is.doc(docId);
      	retVal.add(new RSSItem(
      			d.getField("source").stringValue(), 
      			d.getField("sourceUrl").stringValue(), 
      			d.getField("title").stringValue(), 
      			d.getField("link").stringValue(), 
      			d.getField("pubDate").stringValue(), 
      			d.getField("description").stringValue()));
      }
      

    Testované zdroje:

    Na výslednej aplikácii boli testované nasledovné RSS zdroje v rôznych časových intervaloch, indexovanie a vyhľadávanie informácií v nich prebiehalo bez problémov.

    http://www.cas.sk/rss
    http://rss.sme.sk/rss/rss.asp?id=frontpage
    http://www.aktuality.sk/rss
    http://aktualne.centrum.sk/export/rss-hp.phtml
    http://www.ta3.com/sk/rss/ta3
    http://www.24hod.sk/rss/24hod.xml
     

    Inštalácia aplikácie

    V rar súbore je priložený ukážkový zoznam rss kanálov a spustiteľný jar archív. Nie je nutná žiadna špeciálna inštalácia, stači mať na PC nainštalovaný java runtime a spustiť jar.

    Po spustení aplikácie:

    "Get sources..." - načítame súbor s RSS linkami

    "Check data availability" - skontrolujeme dostupnosť RSS dokumentov na načítaných linkách

    "Download & Index" - stiahne dokumenty do lucene indexu

    Po absolvovaní týchto krokov je možné jednoducho vyhľadávať. Nutné pamätať, že ak zadáme len časť slova, treba použiť * inak vyhľadáva slovo v presnom znení a nemusí nič nájsť (pri eur nenájde slovo euro).

    Zhodnotenie:

     V zhodnotení som sa snažil o porovnávanie s Google Readrom, webovou RSS čítačkou od Google. Pri porovnávaní som pridal do googlu tie isté rss zdroje ako do svojho programu. Prvá vec ktorá upútala pozornosť bolo to, že aj ked sme do googlu pridali zdroj ktorý obsahoval len malý počet zdrojov napr. 10, google automaticky sprístupnil svoje archívy daného zdroja, pri niektorých sa staršie články datovali aj rokom 2006.

    Nasledoval pokus vyhľadávania v dokumentoch. Google reader nepodporuje takzv. wildcards ako lucene, takze pre vyhľadávacie reťazce ako "lond?n" a "eur*" nevrátil žiadne záznamy. Naopak oproti lucene umožnuje automatické vyhľadávanie bez diakritiky, takže "londýn" je to isté ako "londyn".

    Vyhľadávanie podľa presných slov ukazovalo rovnaké výsledky na prvých miestach (zoradenie podľa dátumu), v googli za nimi nasledoval veľký počet archívnych článkov ku ktorým nemal môj program prístup.

    Tag page (Edit tags)
    • No tags
    You must login to post a comment.
    Powered by MindTouch Core