Recherche en texte intégral avec Solr

Recherche en texte intégral avec Solr

1. Vue d'ensemble

Dans cet article, nous allons explorer un concept fondamental du moteur de rechercheApache Solr: la recherche en texte intégral.

The Apache Solr is an open source framework, designed to deal with millions of documents. Nous allons passer en revue les fonctionnalités de base de celui-ci avec des exemples utilisant la bibliothèque Java -SolrJ.

2. Configuration Maven

Étant donné que Solr est open source, nous pouvons simplement télécharger le fichier binaire et démarrer le serveur séparément de notre application.

Pour communiquer avec le serveur, nous allons définir la dépendance Maven pour le client SolrJ:


    org.apache.solr
    solr-solrj
    6.4.2

Vous pouvez trouver la dernière dépendancehere.

3. Indexation des données

Pour indexer et rechercher des données, nous devons créer uncore; nous allons en créer un nomméitem pour indexer nos données.

Avant de faire cela, nous avons besoin que les données soient indexées sur le serveur, de sorte qu’elles puissent faire l’objet d’une recherche.

There are many different ways we can index data. Nous pouvons utiliser des gestionnaires d'importation de données pour importer des données directement à partir de bases de données relationnelles, télécharger des données avec Solr Cell à l'aide d'Apache Tika ou télécharger des données XML / XSLT, JSON et CSV à l'aide de gestionnaires d'index.

3.1. Indexation du document Solr

Nous pouvons indexer les données dans uncore en créantSolrInputDocument. Tout d'abord, nous devons remplir le document avec nos données, puis n'appeler que l'API de SolrJ pour indexer le document:

SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", id);
doc.addField("description", description);
doc.addField("category", category);
doc.addField("price", price);
solrClient.add(doc);
solrClient.commit();

Notez queid doit naturellement être unique pour différentsitems. Avoir unid d'un document déjà indexé mettra à jour ce document.

3.2. Indexation des haricots

SolrJ fournit des API pour indexer les beans Java. Pour indexer un bean, nous devons l'annoter avec les annotations@Field:

public class Item {

    @Field
    private String id;

    @Field
    private String description;

    @Field
    private String category;

    @Field
    private float price;
}

Une fois que nous avons le haricot, l'indexation est simple:

solrClient.addBean(item);
solrClient.commit();

4. Requêtes Solr

La recherche est la capacité la plus puissante de Solr. Une fois les documents indexés dans notre référentiel, nous pouvons rechercher des mots-clés, des expressions, des plages de dates, etc. Les résultats sont triés par pertinence (score).

4.1. Requêtes de base

Le serveur expose une API pour les opérations de recherche. Nous pouvons appeler les gestionnaires de requêtes/select ou/query.

Faisons une recherche simple:

SolrQuery query = new SolrQuery();
query.setQuery("brand1");
query.setStart(0);
query.setRows(10);

QueryResponse response = solrClient.query(query);
List items = response.getBeans(Item.class);

SolrJ utilisera en interne le paramètre de requête principalq dans sa requête au serveur. Le nombre d'enregistrements renvoyés sera de 10, indexés à partir de zéro lorsquestart etrows ne sont pas spécifiés.

La requête de recherche ci-dessus recherchera tous les documents contenant le mot complet“brand1” dans l'un de ses champs indexés. Notez quesimple searches are not case sensitive.

Let’s look at another example. Nous voulons rechercher n'importe quel mot contenant“rand”, qui commence par un nombre quelconque de caractères et se termine par un seul caractère. Nous pouvons utiliser les caractères génériques* et? dans notre requête:

query.setQuery("*rand?");

Les requêtes Solr supportent également les opérateurs booléens comme en SQL:

query.setQuery("brand1 AND (Washing OR Refrigerator)");

Tous les opérateurs booléens doivent être en majuscules; ceux sauvegardés par l'analyseur de requêtes sontAND,OR, NOT,+ et -.

De plus, si nous voulons effectuer une recherche sur des champs spécifiques au lieu de tous les champs indexés, nous pouvons les spécifier dans la requête:

query.setQuery("description:Brand* AND category:*Washing*");

4.2. Requêtes d'expressions

Jusqu'à présent, notre code cherchait des mots-clés dans les champs indexés. Nous pouvons également faire des recherches d'expressions sur les champs indexés:

query.setQuery("Washing Machine");

Lorsque nous avons une expression comme «Washing Machine», l’analyseur de requêtes standard de Solr l’analyse en «Washing OR Machine». Pour rechercher une phrase entière, nous pouvons uniquement ajouter l'expression entre guillemets:

query.setQuery("\"Washing Machine\"");

We can use proximity search to find words within specific distances. Si nous voulons trouver les mots qui sont séparés d'au moins deux mots, nous pouvons utiliser la requête suivante:

query.setQuery("\"Washing equipment\"~2");

4.3. Requêtes de plage

Les requêtes de plage permettent d'obtenir des documents dont les champs sont situés entre des plages spécifiques.

Supposons que nous recherchions des articles dont le prix varie entre 100 et 300:

query.setQuery("price:[100 TO 300]");

La requête ci-dessus trouvera tous les éléments dont le prix est compris entre 100 et 300 inclus. Nous pouvons utiliser «}» et «\{» pour exclure les points finaux:

query.setQuery("price:{100 TO 300]");

4.4. Filtrer les requêtes

Les requêtes de filtrage peuvent être utilisées pour restreindre le sur-ensemble de résultats pouvant être renvoyés. La requête de filtrage n'influence pas le score:

SolrQuery query = new SolrQuery();
query.setQuery("price:[100 TO 300]");
query.addFilterQuery("description:Brand1","category:Home Appliances");

En règle générale, la requête de filtre contient les requêtes couramment utilisées. Comme ils sont souvent réutilisables, ils sont mis en cache pour rendre la recherche plus efficace.

Facettage aide à organiser les résultats de la recherche en comptes de groupe. Nous pouvons traiter des champs, des requêtes ou des plages.

5.1. Facettage sur le terrain

Par exemple, nous voulons obtenir les comptes agrégés des catégories dans le résultat de la recherche. Nous pouvons ajouter le champcategory dans notre requête:

query.addFacetField("category");

QueryResponse response = solrClient.query(query);
List facetResults = response.getFacetField("category").getValues();

LesfacetResults contiendront les décomptes de chaque catégorie dans les résultats.

5.2. Facettage de requête

Le faceting de requête est très utile lorsque nous voulons ramener le nombre de sous-requêtes:

query.addFacetQuery("Washing OR Refrigerator");
query.addFacetQuery("Brand2");

QueryResponse response = solrClient.query(query);
Map facetQueryMap = response.getFacetQuery();

En conséquence, lesfacetQueryMap auront des nombres de requêtes à facettes.

5.3. Facettage de gamme

Le facettage de la plage est utilisé pour obtenir le nombre de plages dans les résultats de la recherche. La requête suivante renvoie les comptes de plages de prix compris entre 100 et 251, séparés de 25:

query.addNumericRangeFacet("price", 100, 275, 25);

QueryResponse response = solrClient.query(query);
List rangeFacets =  response.getFacetRanges().get(0).getCounts();

Outre les plages numériques, Solr prend également en charge les plages de dates, les facettes par intervalles et par pivot.

6. Appuyez sur la mise en évidence

Nous souhaitons peut-être que les mots-clés de notre requête de recherche soient mis en évidence dans les résultats. Cela sera très utile pour obtenir une meilleure image des résultats. Indexons quelques documents et définissons les mots-clés à mettre en évidence:

itemSearchService.index("hm0001", "Brand1 Washing Machine", "Home Appliances", 100f);
itemSearchService.index("hm0002", "Brand1 Refrigerator", "Home Appliances", 300f);
itemSearchService.index("hm0003", "Brand2 Ceiling Fan", "Home Appliances", 200f);
itemSearchService.index("hm0004", "Brand2 Dishwasher", "Washing equipments", 250f);

SolrQuery query = new SolrQuery();
query.setQuery("Appliances");
query.setHighlight(true);
query.addHighlightField("category");
QueryResponse response = solrClient.query(query);

Map>> hitHighlightedMap = response.getHighlighting();
Map> highlightedFieldMap = hitHighlightedMap.get("hm0001");
List highlightedList = highlightedFieldMap.get("category");
String highLightedText = highlightedList.get(0);

Nous obtiendrons leshighLightedText sous la forme“Home <em>Appliances</em>”. Veuillez noter que le mot-clé de rechercheAppliances est balisé avec<em>. La balise de mise en évidence par défaut utilisée par Solr est<em>, mais nous pouvons changer cela en définissant les balisespre etpost:

query.setHighlightSimplePre("");
query.setHighlightSimplePost("");

7. Suggestions de recherche

Les suggestions sont l’une des fonctionnalités importantes supportées par Solr. Si les mots-clés de la requête contiennent des fautes d'orthographe ou si nous voulons suggérer de compléter automatiquement un mot-clé de recherche, nous pouvons utiliser la fonctionnalité de suggestion.

7.1. Vérification orthographique

Le gestionnaire de recherche standard n'inclut pas de composant de vérification orthographique; il doit être configuré manuellement. Il y a trois façons de le faire. Vous pouvez trouver les détails de la configuration dans leswiki page officiels. Dans notre exemple, nous utiliseronsIndexBasedSpellChecker, qui utilise des données indexées pour la vérification orthographique des mots clés.

Cherchons un mot clé avec une faute d'orthographe:

query.setQuery("hme");
query.set("spellcheck", "on");
QueryResponse response = solrClient.query(query);

SpellCheckResponse spellCheckResponse = response.getSpellCheckResponse();
Suggestion suggestion = spellCheckResponse.getSuggestions().get(0);
List alternatives = suggestion.getAlternatives();
String alternative = alternatives.get(0);

L'alternative attendue pour notre mot-clé“hme” doit être“home” car notre index contient le terme“home”. Notez quespellcheck doit être activé avant d'exécuter la recherche.

7.2. Suggestion automatique de termes

Nous voudrons peut-être obtenir les suggestions de mots-clés incomplets pour faciliter la recherche. Le composant suggéré par Solr doit être configuré manuellement. Vous pouvez trouver les détails de la configuration dans seswiki page officiels.

Nous avons configuré un gestionnaire de requêtes nommé/suggest pour gérer les suggestions. Obtenons des suggestions pour le mot clé“Hom”:

SolrQuery query = new SolrQuery();
query.setRequestHandler("/suggest");
query.set("suggest", "true");
query.set("suggest.build", "true");
query.set("suggest.dictionary", "mySuggester");
query.set("suggest.q", "Hom");
QueryResponse response = solrClient.query(query);

SuggesterResponse suggesterResponse = response.getSuggesterResponse();
Map> suggestedTerms = suggesterResponse.getSuggestedTerms();
List suggestions = suggestedTerms.get("mySuggester");

La listesuggestions doit contenir tous les mots et expressions. Notez que nous avons configuré un suggester nommémySuggester dans notre configuration.

8. Conclusion

Cet article est une introduction rapide aux capacités et fonctionnalités de Solr du moteur de recherche.

Nous avons abordé de nombreuses fonctionnalités, mais celles-ci ne font bien sûr qu'effleurer ce que nous pouvons faire avec un serveur de recherche avancé et évolué tel que Solr.

Les exemples utilisés ici sont disponibles comme toujours,over on GitHub.