[JAVA] Erstellen Sie Ihre eigene Solr-Funktionsabfrage

Solrs Funktionsabfrage enthält viele nützliche Dinge:

https://wiki.apache.org/solr/FunctionQuery#Available_Functions

Ich denke, dass die oben genannten Funktionen allein möglicherweise nicht den Anforderungen entsprechen.

Dieses Mal werde ich eine FunctionQuery erstellen, indem ich davon ausgehe, dass die in einem bestimmten Feld registrierte Zeichenfolge im JSON-Format analysiert wird, eine gewisse Verarbeitung durchgeführt wird und dann das Ergebnis zurückgegeben wird.

Dieser Beitrag http://www.lifull.blog/entry/2014/02/25/145220 Ich habe es mit Bezug auf erstellt. Der obige Artikel ist genug, um hilfreich zu sein, also denke ich, dass einige Leute ihre eigenen machen können. In diesem Artikel werden wir uns den Solr-Quellcode genauer ansehen und ihn erstellen, einschließlich Erläuterungen zu seiner Klassenstruktur.

Wie werden die Standardfunktionen implementiert?

Lesen Sie zunächst die Implementierung der standardmäßig bereitgestellten Funktionen.

https://github.com/apache/lucene-solr/blob/master/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java Die bereitgestellte FunctionQuery wird als Objekt der ValueSourceParser-Klasse in der obigen Quelle implementiert.

Die ValueSourceParser-Klasse hat die folgenden Signaturen:

public abstract class ValueSourceParser implements NamedListInitializedPlugin {
  /**
   * Initialize the plugin.
   */
  @Override
  public void init(NamedList args) {}

  /**
   * Parse the user input into a ValueSource.
   */
  public abstract ValueSource parse(FunctionQParser fp) throws SyntaxError;

  ...

Außerdem im Initialisierungsblock </ span> der ValueSourceParser-Klasse

addParser("abs", new ValueSourceParser() {
  @Override
  public ValueSource parse(FunctionQParser fp) throws SyntaxError {
    ValueSource source = fp.parseValueSource();
    return new SimpleFloatFunction(source) {
      @Override
      protected String name() {
        return "abs";
      }

      @Override
      protected float func(int doc, FunctionValues vals) {
        return Math.abs(vals.floatVal(doc));
      }
    };
  }
});

Die Standardfunktion wird wie folgt erstellt.

bitte beachten Sie

ist.

Die Definition von SimpleFloatFunction lautet

https://github.com/apache/lucene-solr/blob/master/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/SimpleFloatFunction.java

Es ist definiert in.

...
/** A simple float function with a single argument
 */
 public abstract class SimpleFloatFunction extends SingleFunction {
  public SimpleFloatFunction(ValueSource source) {
    super(source);
  }

  protected abstract float func(int doc, FunctionValues vals) throws IOException;

  @Override
  public FunctionValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
    final FunctionValues vals =  source.getValues(context, readerContext);
    return new FloatDocValues(this) {
      @Override
      public float floatVal(int doc) throws IOException {
        return func(doc, vals);
      }
      @Override
      public String toString(int doc) throws IOException {
        return name() + '(' + vals.toString(doc) + ')';
      }
    };
  }
...

Es liest das abs () - Argument in einer Methode namens getValues und gibt eine Instanz der FloatDocValues-Klasse zurück (die von der FunctionValues-Klasse erbt). Die floatVal-Methode der FloatDocValues-Klasse ruft die Overridden-func-Methode (#initialize) auf, um die Math.abs-Funktion aufzurufen, die letztendlich den absoluten Wert zurückgibt.

https://github.com/apache/lucene-solr/blob/master/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/

Wenn Sie sich einige der im obigen Verzeichnis definierten Klassen ansehen, sehen Sie dasselbe.

Es ist implementiert als.

Ebenfalls, https://wiki.apache.org/solr/SolrPlugins#ValueSourceParser

Wenn Sie sich das obige Dokument ansehen, können Sie Ihre eigene Klasse erstellen und ihr einen Funktionsnamen geben, indem Sie sie in "solrconfig.xml" setzen.

Aus dem oben Gesagten ist die notwendige Arbeit

  1. Erstellen Sie eine Klasse, die die ValueSourceParser-Klasse erbt
  2. Erstellen Sie eine Klasse, um Argumente wie die SimpleFloatFunction-Klasse zu verarbeiten, und überschreiben Sie die func-Methode, um schließlich eine Instanz der Klasse (FloatDocValues usw.) zu erstellen und zurückzugeben, die dem Werttyp entspricht, den Sie zurückgeben möchten.

Dieses Mal möchte ich eine FunctionQuery erstellen, die eine Zeichenfolge als Argument verwendet und einen Bool-Typ zurückgibt

https://github.com/apache/lucene-solr/blob/master/lucene/queries/src/java/org/apache/lucene/queries/function/valuesource/SimpleBoolFunction.java

Es scheint, dass diese einfache Bool-Funktion verwendet werden kann.

/**
 * {@link BoolFunction} implementation which applies an extendible boolean
 * function to the values of a single wrapped {@link ValueSource}.
 *
 * Functions this can be used for include whether a field has a value or not,
 * or inverting the boolean value of the wrapped ValueSource.
 */
public abstract class SimpleBoolFunction extends BoolFunction {
  protected final ValueSource source;

  public SimpleBoolFunction(ValueSource source) {
    this.source = source;
  }

  protected abstract String name();

  protected abstract boolean func(int doc, FunctionValues vals) throws IOException;

  @Override
  public BoolDocValues getValues(Map context, LeafReaderContext readerContext) throws IOException {
    final FunctionValues vals =  source.getValues(context, readerContext);
    return new BoolDocValues(this) {
      @Override
      public boolean boolVal(int doc) throws IOException {
        return func(doc, vals);
      }
      @Override
      public String toString(int doc) throws IOException {
        return name() + '(' + vals.toString(doc) + ')';
      }
    };
  }

Wenn Sie die notwendige Arbeit umschreiben

  1. Erstellen Sie eine ursprüngliche Klasse, die die ValueSourceParser-Klasse erbt
  2. Erstellen Sie eine Klasse, die SimpleBoolFunction erbt, und überschreiben Sie die func-Methode

Wird sein. Führen Sie die obigen Arbeiten aus, um Ihre eigene Funktionsabfrage zu erstellen.

Erstellen Sie eine ursprüngliche Klasse, die die ValueSourceParser-Klasse erbt

package com.overseas_lifull.solr.functionquery;

import org.apache.lucene.queries.function.ValueSource;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.search.SyntaxError;
import org.apache.solr.search.FunctionQParser;
import org.apache.solr.search.ValueSourceParser;

public class PremiumParser extends ValueSourceParser {
    @Override
    public void init(NamedList namedList) {
    }

    @Override
    public ValueSource parse(FunctionQParser fp) throws SyntaxError {
        ValueSource premiumInfo = fp.parseValueSource();

        return new PremiumFunction(premiumInfo);
    }
}

Der im Argument empfangene Wert von premiumInfo wird an die Funktion PremiumFunction übergeben, die später definiert wird. Diese PremiumFunction ist eine Klasse, die SimpleBoolFunction erbt.

Erstellen Sie eine Klasse, die SimpleBoolFunction erbt, und überschreiben Sie die func-Methode

package com.overseas_lifull.solr.functionquery;

import org.apache.lucene.queries.function.ValueSource;
import org.apache.lucene.queries.function.FunctionValues;
import org.apache.lucene.queries.function.valuesource.SimpleBoolFunction;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.Date;

public class PremiumFunction extends SimpleBoolFunction {

    public PremiumFunction(ValueSource source) {
        super(source);
    }

    protected String name() {
        return "isPremium";
    }

    protected boolean func(int doc, FunctionValues vals) {
        boolean result = false;
        String jsonStr = vals.strVal(doc); //Rufen Sie das Argument der Funktion isPremium als Zeichenfolge ab
        /*Verarbeiten Sie die Zeichenfolge und true,Gibt false zurück
         * ...Verschiedene Verarbeitung*/
        if (/*Urteilsbedingung*/) {
          return true;
        } else {
          return false;
        }
    }
}

Kompilieren Sie es, legen Sie es in dem von Solr erwarteten Verzeichnis ab und bearbeiten Sie solrconfig.xml.

kompilieren

$ javac -classpath "./lib/*:/opt/solr-5.5.3/server/solr-webapp/webapp/WEB-INF/lib/lucene-core-5.5.3.jar:/opt/solr-5.5.3/server/solr-webapp/webapp/WEB-INF/lib/lucene-queries-5.5.3.jar:/opt/solr-5.5.3/server/solr-webapp/webapp/WEB-INF/lib/lucene-queryparser-5.5.3.jar:/opt/solr-5.5.3/server/solr-webapp/webapp/WEB-INF/lib/solr-core-5.5.3.jar:/opt/solr-5.5.3/server/solr-webapp/webapp/WEB-INF/lib/solr-solrj-5.5.3.jar" com/overseas_lifull/solr/functionquery/PremiumFunction.java com/overseas_lifull/solr/functionquery/PremiumParser.java com/overseas_lifull/solr/functionquery/PremiumData.java

Der von Ihnen angegebene Klassenpfad hängt von der verwendeten Klasse und dem Speicherort der Quelle ab.

Erstellung von JAR-Dateien

$ jar cvf premiumQueryFunction.jar ./com/overseas_lifull/solr/functionquery/PremiumData.class ./com/overseas_lifull/solr/functionquery/PremiumData.java ./com/overseas_lifull/solr/functionquery/PremiumFunction.class ./com/overseas_lifull/solr/functionquery/PremiumFunction.java ./com/overseas_lifull/solr/functionquery/PremiumParser.class ./com/overseas_lifull/solr/functionquery/PremiumParser.java

Platzierung von JAR-Dateien

Erstellen Sie ein lib-Verzeichnis im Solr-Kernverzeichnis und platzieren Sie es dort.

Die Verzeichnisstruktur sollte wie folgt aussehen.

conf/
  admin-extra.html
  admin-extra.menu-bottom.html
  admin-extra.menu-top.html
  data-config.xml
  dataimport.properties
  elevate.xml
  schema.xml
  solrconfig.xml
lib/
  premiumQueryFunction.jar
core.properties

Bearbeiten Sie solrconfig.xml

<valueSourceParser name="isPremium" class="com.overseas_lifull.solr.functionquery.PremiumParser" />

Starten Sie Solr neu

Starten Sie Solr neu, um die bearbeitete sorlconfig.xml und die platzierte JAR-Datei zu laden.

Versuchen Sie, eine Abfrage zu werfen

http://localhost:8983/solr/my_core/select?q=*:*&fl=*,isPremium(flat_premium_data)&wt=json&indent=true

In dem Dokument als Antwort zurückgegeben Es ist erfolgreich, wenn es ein Feld und einen Wert (wahr oder falsch) wie "isPremium (flat_premium_data): true" gibt.

Recommended Posts

Erstellen Sie Ihre eigene Solr-Funktionsabfrage
Erstellen Sie Ihre eigenen Java-Anmerkungen
Erstellen Sie Ihre eigene Codierung für String.getBytes ()
Erstellen Sie Ihren eigenen Validator mit Bean Validation
Verwendung der Talend-Komponente (5) Erstellen Sie Ihre eigene Komponente
Erstellen Sie Ihre eigene Android-App für das Java-Lernen
Erstellen Sie Ihr eigenes Dienstprogramm mit Thymeleaf mit Spring Boot
Machen Sie Ihren eigenen Pomodoro
Optimieren Sie Ihre Anfrage mit EXPLAIN
Erstellen Sie Ihr eigenes Elasticsearch-Plugin
So erstellen Sie mit Spring Boot einen eigenen Controller, der / error entspricht