Fusion arbeitet für Sie: Eine benutzerdefinierte Sitemap Crawler JavaScript-Stufe

Eine der leistungsfähigsten Funktionen von Fusion ist die integrierte JavaScript-Stufe. Allerdings sollten Sie diese Stufe nicht einfach nur als JavaScript-Stufe…

Eine der leistungsfähigsten Funktionen von Fusion ist die integrierte JavaScript-Stufe. Allerdings sollten Sie diese Stufe nicht einfach nur als JavaScript-Stufe betrachten. Fusion verwendet die Nashorn JavaScript-Engine, d.h. Sie haben Zugriff auf alle in der Anwendung verwendeten Java-Klassenbibliotheken. Das bedeutet, dass Sie effektiv Ihre eigenen angepassten Java- und/oder JavaScript-Verarbeitungsschritte skripten können und die Indexierungspipeline wirklich so für Sie arbeiten lassen können, wie Sie es möchten.

Zunächst einmal müssen wir uns also mit Nashorn JavaScript vertraut machen. Nashorn (deutsch für Rhinozeros) wurde gegen Ende 2012 veröffentlicht. Es ist zwar viel schneller als sein Vorgänger Rhino, aber es enthält auch eine lang ersehnte Funktion: Die Kombination von Java und JavaScript. Obwohl es sich um zwei völlig unterschiedliche Sprachen handelt, hatten diese beiden, wie man so schön sagt, schon seit langem „ein Date mit dem Schicksal“.

 

Hallo Welt

Lassen Sie uns zunächst einen Blick auf die grundlegendste Funktion in einer Fusion JavaScript Stage werfen:

function(doc){
   logger.info("Doc ID: "+doc.getId());
return doc;
}

Im Grunde ist dies die grundlegendste Funktion. Beachten Sie, dass Sie ein ‚doc‘-Argument übergeben, das immer ein PipelineDocument ist, und dass Sie dieses Dokument zurückgeben (oder alternativ ein Array von Dokumenten, aber das ist eine andere Geschichte, die wir in einem separaten Artikel behandeln werden). Die ‚id‘ dieses Dokuments ist die URL, die gecrawlt wird, und dank des Tika Parsers ist das Attribut ‚body‘ das Roh-XML unseres RSS-Feeds.

Zu diesem Zweck öffnen Sie als erstes Ihren Pipeline-Editor und wählen den Apache Tika Parser aus. Vergewissern Sie sich, dass die Kontrollkästchen „Geparste Inhalte als XML oder HTML zurückgeben“ und „Original-XML und HTML anstelle der Tika-XML-Ausgabe zurückgeben“ aktiviert sind. Der Tika Parser wird in diesem Fall wirklich nur dazu verwendet, das RSS-XML aus dem Feed, den Sie crawlen möchten, zu holen. Der Rest der Verarbeitung wird in unserer benutzerdefinierten JavaScript-Phase durchgeführt.

Fügen wir nun die Stufe zu unserer Indizierungs-Pipeline hinzu. Klicken Sie auf „Stufe hinzufügen“ und wählen Sie die Stufe „JavaScript“ aus dem Menü.

Unsere Funktion wird in zwei Phasen arbeiten. In der ersten Phase wird das Roh-XML aus dem Dokument gezogen und mit Jsoup geparst, um eine java.util.ArrayList der zu crawlenden URLs zu erstellen. In der zweiten Phase wird Jsoup verwendet, um Text aus den verschiedenen Elementen zu extrahieren und sie in das PipelineDocument zu setzen. Unsere Funktion gibt die ArrayList der geparsten Dokumente zurück und sendet sie an die Solr Indexing Stage.

Nachdem wir nun also unsere Prozesse definiert haben, können wir die Arbeit zeigen:

 

Parsen des XML, Parsen des HTML

            
      function (doc) {
        var doclist = java.util.ArrayList;
        var Jsoup = org.jsoup.Jsoup;
        var jdoc = org.jsoup.nodes.Document;
        var ex = java.lang.Exception;
        var Parser = org.jsoup.parser.Parser;
        var element = org.jsoup.Element;
        var pipelineDoc = com.lucidworks.apollo.common.pipeline.PipelineDocument;
        var xmlstr = java.lang.String;
        var docurl = java.lang.String;
        var elements = org.jsoup.select.Elements;
        var ele = org.jsoup.Element;
        var outdocs = java.util.ArrayList;
        doclist = new java.util.ArrayList();
        outdocs = new java.util.ArrayList();
        var elementsToExtract = ["p","span","div","a"];
        var targetElement = "loc";
        
        try {


            xmlstr = doc.getFirstFieldValue("body");
            jdoc = Jsoup.parse(xmlstr, "", Parser.xmlParser());
            for each(element in jdoc.select(targetElement)) {
                docurl = element.ownText();
                if (docurl !== null && docurl !== "") {
                    logger.info("Parsed URL: " + element.ownText());
                    pipelineDoc = new com.lucidworks.apollo.common.pipeline.PipelineDocument(element.ownText());
                    doclist.add(pipelineDoc);
                }

            }

        } catch (ex) {
            logger.error(ex);
        }

        try {
            for each(pipelineDoc in doclist) {
                docurl = pipelineDoc.getId();
                jdoc = Jsoup.connect(docurl).get();
                extractedText = new java.lang.String();
                if (jdoc !== null) {
                    logger.info("FOUND a JSoup document for url  " + docurl);
                    var extractedText = new java.lang.String();
                    var metaDataText = new java.lang.String();
                    // get the title
                    ele = jdoc.select("title").first();
                    if(ele !== null && ele.ownText){
                      pipelineDoc.addField("title", ele.ownText());
                    }
                    
                    // get the meta 
                     ele = jdoc.select("meta[keywords]").first();
                     if(ele !== null && ele.ownText){
                        pipelineDoc.addField("meta.keywords", ele.ownText());
                    }
                    
                    ele = jdoc.select("meta[description]").first();
                     if(ele !== null && ele.ownText){
                        pipelineDoc.addField("meta.description", ele.ownText());
                    }
                    
                    for each(var val in elementsToExtract){
                    elements = jdoc.select(val);
                    logger.info("ITERATE OVER ELEMENTS");
                    // then parse elements and pull just the text
                    for each (ele in elements) {
                        if (ele !== null) {
                            if (ele.ownText() !== null) {
                                extractedText += " "+ ele.ownText();
                            }
                        }
                    }
                  }
                    pipelineDoc.addField('body', extractedText);
                    logger.info("Extracted: " + extractedText);
                    outdocs.add(pipelineDoc);

                } else {
                    logger.warn("Jsoup Document was NULL **** ");
                }
            }
        } catch (ex) {
            logger.error(ex);
        }

        return outdocs;
    }

In der obigen Funktion wird also zunächst das rohe XML in ein Jsoup-Dokument geparst. Von dort aus iterieren wir über die im Dokument gefundenen Elemente(jdoc.select(„loc“)). Sobald wir eine ArrayList von PipelineDocuments haben (unter Verwendung der URL für die ID), geben wir diese an ein kleines Skript weiter, das diese Liste in einer Schleife durchläuft und wiederum die Jsoup-Selektor-Syntax verwendet, um den gesamten Text aus den Elementen zu extrahieren, z. B.(jdoc.select(„p“)). In diesem Beispiel erstelle ich ein einfaches JavaScript-Array mit 4 Elementen (a, p, div, span) und kompiliere den extrahierten Text. Ich extrahiere auch den Titel des Dokuments und die Meta-Schlüsselwörter/Beschreibung.

Sobald wir den Text extrahiert haben, legen wir alle Felder fest, die für unsere Sammlung relevant sind. Für dieses Beispiel habe ich 4 Felder erstellt: title, body, meta.keywords und meta.description. Beachten Sie, dass ich das Speichern des Rohtextes auskommentiert habe. Sie sollten es vermeiden, Rohtext in Ihre Sammlung aufzunehmen, es sei denn, Sie haben einen konkreten Bedarf dafür. Am besten extrahieren Sie nur die wichtigen Daten/Metadaten und verwerfen den Rohtext.

Nachdem wir nun unsere PipelineDocuments gefüllt haben, gibt die Funktion die ArrayList ‚outdocs‘ an den Pipeline-Prozess zurück, und die Dokumente werden dann von der Solr Indexer Stage persistiert.

Und das ist wirklich alles, was es zu tun gibt. Diese Implementierung wurde mit Fusion 2.4.2 getestet.

You Might Also Like

Vom Suchunternehmen zum praktischen KI-Pionier: Unsere Vision für 2025 und darüber hinaus

CEO Mike Sinoway gibt Einblicke in die Zukunft der KI und stellt...

Read More

Wenn KI schief geht: Fehlschläge in der realen Welt und wie man sie vermeidet

Lassen Sie nicht zu, dass Ihr KI-Chatbot einen 50.000 Dollar teuren Tahoe...

Read More

Lucidworks Kernpakete: Branchenoptimierte KI-Such- und Personalisierungslösungen

Entdecken Sie unsere umfassenden Core Packages, die Analytics Studio, Commerce Studio und...

Read More

Quick Links