Red Hat Training

A Red Hat training course is available for Red Hat JBoss Enterprise Application Platform

13.3.3. Filters

Lucene Apache possède une fonctionnalité importante vous permettant de filtrer les résultats de votre requête selon un procédé de filtrage pesonnalisé. C'est une façon très efficace d'appliquer des restrictions de données additionnelles, notamment car les filtres peuvent être mis en cache et réutilisés. Voici quelques cas d'utilisation :
  • sécurité
  • données temporelles (par exemple, afficher uniquement les données du mois précédent)
  • filtre de population (par exemple, recherche limitée à une catégorie donnée)

13.3.3.1. Utilisation des filtres dans un environnement partitionné

Pour exécuter des requêtes sur un sous-ensemble des partitions disponibles dans un environnement partitionné, veuillez suivre les deux étapes suivantes :

Procédure 13.1. Requête de sous-ensemble de partitions d'index

  1. Créer une stratégie de partitionnement qui sélectionne un sous-ensemble de IndexManagers selon la configuration du filtre.
  2. Activer le filtre au moment de la requête.

Exemple 13.49. Requête de sous-ensemble de partitions d'index

Dans l'exemple ci-dessous, la requête est effectuée pour une partition de client spécifique si le filtre customer (client) est activé.
public class CustomerShardingStrategy implements IndexShardingStrategy {
	
	 // stored IndexManagers in a array indexed by customerID
	 private IndexManager[] indexManagers;
	 
	 public void initialize(Properties properties, IndexManager[] indexManagers) {
	   this.indexManagers = indexManagers;
	 }
	
	 public IndexManager[] getIndexManagersForAllShards() {
	   return indexManagers;
	 }
	
	 public IndexManager getIndexManagerForAddition(
	     Class<?> entity, Serializable id, String idInString, Document document) {
	   Integer customerID = Integer.parseInt(document.getFieldable("customerID").stringValue());
	   return indexManagers[customerID];
	 }
	
	 public IndexManager[] getIndexManagersForDeletion(
	     Class<?> entity, Serializable id, String idInString) {
	   return getIndexManagersForAllShards();
	 }
	
	  /**
	  * Optimization; don't search ALL shards and union the results; in this case, we 
	  * can be certain that all the data for a particular customer Filter is in a single
	  * shard; simply return that shard by customerID.
	  */
	 public IndexManager[] getIndexManagersForQuery(
	     FullTextFilterImplementor[] filters) {
	   FullTextFilter filter = getCustomerFilter(filters, "customer");
	   if (filter == null) {
	     return getIndexManagersForAllShards();
	   }
	   else {
	     return new IndexManager[] { indexManagers[Integer.parseInt(
	       filter.getParameter("customerID").toString())] };
	   }
	 }
	
	 private FullTextFilter getCustomerFilter(FullTextFilterImplementor[] filters, String name) {
	   for (FullTextFilterImplementor filter: filters) {
	     if (filter.getName().equals(name)) return filter;
	   }
	   return null;
	 }
	}
Dans cet exemple, si le filtre intitulé customer est présent, seule la partition consacrée à ce client sera requise, sinon, toutes les partitions seront retournées. Une stratégie de partitionnement donnée peut réagir à un ou plusieurs filtres et dépendra de ces paramètres.
La deuxième étape sert simplement à activer le filtre au moment de la requête. Le filtre peut être standard (tel que défini dans Section 13.3.3, « Filters ») et filtrer les résultats Lucene suite à la requête, ou vous pouvez utiliser un filtre spécial qui ne sera appliqué que pour la stratégie de partitionnement et ignoré pour le reste de la requête. Pour utiliser cette fonction, veuillez spécifier la classe ShardSensitiveOnlyFilter lorsque vous indiquez votre filtre.
@Indexed
@FullTextFilterDef(name="customer", impl=ShardSensitiveOnlyFilter.class)
public class Customer {
   ...
}

FullTextQuery query = ftEm.createFullTextQuery(luceneQuery, Customer.class);
query.enableFulltextFilter("customer").setParameter("CustomerID", 5);
@SuppressWarnings("unchecked")
List<Customer> results = query.getResultList();
Veuillez noter qu'en utilisant le filtre ShardSensitiveOnlyFilter, vous n'aurez pas besoin de mettre en place un filtre Lucene. L'utilisation de filtres et d'une stratégie de partitionnement réagissant à ces filtres est recommandée pour accélérer les requêtes dans un environnement partitionné.