[JAVA] Créez votre propre requête de fonction Solr

La requête de fonction de Solr a beaucoup de choses utiles,

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

Je pense que les fonctions ci-dessus à elles seules peuvent ne pas répondre aux exigences.

Cette fois, je vais créer une FunctionQuery en supposant que la chaîne de caractères au format JSON enregistrée dans un certain champ est analysée, un traitement est effectué, puis le résultat est renvoyé.

Cet article http://www.lifull.blog/entry/2014/02/25/145220 Je l'ai créé en référence à. L'article ci-dessus est suffisant pour être utile, je pense donc que certaines personnes peuvent créer le leur. Dans cet article, nous examinerons de plus près le code source de Solr et le créerons, en expliquant notamment le type de structure de classe dont il dispose.

Comment les fonctions par défaut sont-elles implémentées?

Tout d'abord, reportez-vous à l'implémentation des fonctions fournies par défaut.

https://github.com/apache/lucene-solr/blob/master/solr/core/src/java/org/apache/solr/search/ValueSourceParser.java La FunctionQuery fournie est implémentée en tant qu'objet de la classe ValueSourceParser dans la source ci-dessus.

La classe ValueSourceParser a les signatures suivantes:

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;

  ...

De plus, dans le bloc d'initialisation </ span> de la classe ValueSourceParser

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));
      }
    };
  }
});

La fonction par défaut est créée comme suit.

Notez s'il vous plaît

est.

La définition de SimpleFloatFunction est

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

Il est défini dans.

...
/** 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) + ')';
      }
    };
  }
...

Il lit l'argument abs () dans une méthode appelée getValues et renvoie une instance de la classe FloatDocValues (qui hérite de la classe FunctionValues). La méthode floatVal de la classe FloatDocValues appelle la méthode Overridden func (#initialize) pour appeler la fonction Math.abs, qui renvoie finalement la valeur absolue.

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

Si vous regardez certaines des classes définies dans le répertoire ci-dessus, vous pouvez voir la même chose.

Il est implémenté comme.

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

Si vous regardez le document ci-dessus, vous pouvez créer votre propre classe et lui donner un nom de fonction en le définissant dans solrconfig.xml.

De ce qui précède, le travail nécessaire est

  1. Créez une classe qui hérite de la classe ValueSourceParser
  2. Créez une classe pour gérer des arguments comme la classe SimpleFloatFunction et remplacez la méthode func pour enfin créer et renvoyer une instance de la classe (FloatDocValues, etc.) qui correspond au type de valeur que vous souhaitez renvoyer.

Cette fois, je veux créer une FunctionQuery qui prend une chaîne comme argument et renvoie un type Bool

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

Il semble que cette fonction booléenne simple puisse être utilisée.

/**
 * {@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) + ')';
      }
    };
  }

Si vous réécrivez le travail nécessaire

  1. Créez une classe d'origine qui hérite de la classe ValueSourceParser
  2. Créez une classe qui hérite de SimpleBoolFunction et remplacez la méthode func

Sera. Effectuez le travail ci-dessus pour créer votre propre requête de fonction.

Créer une classe originale qui hérite de la classe ValueSourceParser

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);
    }
}

La valeur de premiumInfo reçue dans l'argument est transmise à la fonction appelée PremiumFunction qui sera définie ultérieurement. Cette PremiumFunction est une classe qui hérite de SimpleBoolFunction.

Créer une classe qui hérite de SimpleBoolFunction et remplacer la méthode func

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); //Récupère l'argument de la fonction isPremium sous forme de chaîne
        /*Traiter la chaîne et vrai,Renvoie faux
         * ...Traitement divers*/
        if (/*Condition de jugement*/) {
          return true;
        } else {
          return false;
        }
    }
}

Compilez-le, placez-le dans le répertoire attendu par Solr et éditez solrconfig.xml.

compiler

$ 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

Le chemin de classe que vous spécifiez dépend de la classe que vous utilisez et de l'emplacement de la source.

Création de fichier JAR

$ 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

Placement des fichiers JAR

Créez un répertoire lib dans le répertoire principal de Solr et placez-le là.

La structure des répertoires doit ressembler à celle ci-dessous.

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

Modifier solrconfig.xml

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

Redémarrez Solr

Redémarrez Solr pour charger le sorlconfig.xml édité et le fichier jar placé.

Essayez de lancer une requête

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

Dans le document renvoyé en réponse ʻIsPremium (flat_premium_data): Succès s'il y a un champ et une valeur (vrai ou faux) comme vrai`.

Recommended Posts

Créez votre propre requête de fonction Solr
Créez vos propres annotations Java
Créez votre propre encodage pour String.getBytes ()
Créez votre propre validateur avec Bean Validation
Utilisation du composant Talend (5) Créez votre propre composant
Créez votre propre application Android pour l'apprentissage Java
Créez votre propre utilitaire avec Thymeleaf avec Spring Boot
Faites votre propre pomodoro
Affinez votre requête avec EXPLAIN
Créez votre propre plugin Elasticsearch
Comment créer votre propre contrôleur correspondant à / error avec Spring Boot