Utilisation de la requête continue
En supposant que vous avez indexé les attributs de recherche requis, vous devez maintenant implémenter la requête continue dans votre application. En gardant à l'esprit l'objectif des requêtes continues, la première chose que vous devez faire est de définir tous les rappels qui doivent être exécutés une fois que l'ensemble de résultats de votre requête est modifié de quelque manière que ce soit. Ensuite, nous devons enregistrer la requête continue auprès du serveur de cache.
Si toutes vos applications ne nécessitent pas le suivi d'un ensemble de résultats de requête, vous devez non seulement désinscrire les notifications, mais également désinscrire la requête de votre cache.
Pré-requis
- Pour en savoir plus sur les prérequis standard requis pour travailler avec tous NCache fonctionnalités côté client, veuillez vous référer à la page donnée sur Prérequis de l'API côté client.
- L'indexation des objets interrogeables et leurs attributs doivent d'abord être configurés comme expliqué dans Configuration des index de requête dans le Guide de l'administrateur.
- Le cache doit contenir des données liées aux attributs configurés.
- Pour plus de détails sur l'API, reportez-vous à : ICache, Filtre de données d'événement, Type d'événement, ExécuterReader, S'inscrireCQ, DésinscrireCQ, Annuler l'enregistrement de la notification, Requêtecontinue, S'inscrireNotification
, QueryDataNotificationCallbackQueryDataNotificationCallback, ICacheReader, Fieldcount, Lire, insérer, CQEventArg, Getvalue.
- Pour en savoir plus sur les prérequis standard requis pour travailler avec tous NCache fonctionnalités côté client, veuillez vous référer à la page donnée sur Prérequis de l'API côté client.
- L'indexation des objets interrogeables et leurs attributs doivent d'abord être configurés comme expliqué dans Configuration des index de requête dans le Guide de l'administrateur.
- Le cache doit contenir des données liées aux attributs configurés.
- Pour plus de détails sur l'API, reportez-vous à : Cache, Filtre de données d'événement, Type d'événement, exécuterReader, registreCQ, désinscrireCQ, supprimerDataModificationListener, CacheItem, CacheItemVersionCacheItemVersion, insérer, CQEventArg, getEventType, lire, obtenirValeur, Requêtecontinue, addDataModificationListeneraddDataModificationListener, getFieldCount, Lecteur de cache.
- Pour en savoir plus sur les prérequis standard requis pour travailler avec tous NCache fonctionnalités côté client, veuillez vous référer à la page donnée sur Prérequis de l'API côté client.
- L'indexation des objets interrogeables et leurs attributs doivent d'abord être configurés comme expliqué dans Configuration des index de requête dans le Guide de l'administrateur.
- Le cache doit contenir des données liées aux attributs configurés.
- Pour plus de détails sur l'API, reportez-vous à : Cache, Filtre de données d'événement, Type d'événement, exécuterReader, registreCQ, désinscrireCQ, supprimerDataModificationListener, CacheItem, insérer, getEventType, obtenirValeur, lire, getFieldCount, Requêtecontinue, addDataModificationListeneraddDataModificationListener.
- Pour en savoir plus sur les prérequis standard requis pour travailler avec tous NCache fonctionnalités côté client, veuillez vous référer à la page donnée sur Prérequis de l'API côté client.
- L'indexation des objets interrogeables et leurs attributs doivent d'abord être configurés comme expliqué dans Configuration des index de requête dans le Guide de l'administrateur.
- Le cache doit contenir des données liées aux attributs configurés.
- Pour plus de détails sur l'API, reportez-vous à : get_event_type, exécuter_reader, registre_cq,
un_register_cq, remove_data_modification_listener, CacheItem, insérer, get_field_count, add_data_modification_listener, Requêtecontinue, lire, obtenir_valeur, Type d'événement, CQEventArg.
Étape 1 : Enregistrez le rappel pour les événements
En supposant que vous avez indexé les attributs de recherche requis, vous pouvez implémenter la requête continue dans votre application. Cela nécessite que vous définissiez tous les rappels qui doivent être exécutés une fois que le jeu de résultats de votre requête est modifié. Ensuite, nous devons enregistrer la requête continue auprès du serveur de cache.
Un rappel peut être enregistré pour plusieurs événements.
public void OnChangeInQueryResultSet(string key, CQEventArg arg)
{
switch (arg.EventType)
{
case EventType.ItemAdded:
Console.WriteLine($"Item with key '{key}' has been added to resut set of continuous query");
break;
case EventType.ItemUpdated:
Console.WriteLine($"Item with key '{key}' has been updated in the resut set of continuous query");
// Get updated Product object
// Item can be used if EventDataFilter is DataWithMetadata or Metadata
if (arg.Item != null)
{
Product updatedProduct = arg.Item.GetValue<Product>();
Console.WriteLine($"Updated product '{updatedProduct.ProductName}' with key '{key}' has ID '{updatedProduct.ProductID}'");
}
break;
case EventType.ItemRemoved:
Console.WriteLine($"Item with key '{key}' has been removed from resut set of continuous query");
break;
}
}
public static void onChangeInQueryResultSet(String key, CQEventArg arg) {
switch (arg.getEventType()) {
case ItemAdded:
System.out.println("Item with key '" + key + "' has been added to result set of continuous query");
break;
case ItemUpdated:
System.out.println("Item with key '" + key + "' has been updated in the result set of continuous query");
// Get updated Product object
// Item can be used if EventDataFilter is DataWithMetadata or Metadata
if (arg.getItem() != null) {
Product updatedProduct = (Product) arg.getItem().getValue(Product.class);
System.out.println("Updated product '" + updatedProduct.getProductName() + "' with key '" + key + "' has ID '" + updatedProduct.getProductID() + "'");
}
break;
case ItemRemoved:
System.out.println("Item with key '" + key + "' has been removed from result set of the continuous query");
break;
}
}
// This is an async method
queryItemCallback(key, arg)
{
switch (arg.getEventType())
{
case ncache.ItemAdded:
// Key has been added to the cache
break;
case ncache.ItemUpdated:
// Key has been updated in the cache
// Get updated product object
if (arg.getItem() != null)
{
let updatedProduct = arg.getItem().getValue(Product);
// Perform operations accordingly
}
break;
case ncache.ItemRemoved:
// key has been removed from the cache
break;
}
}
# Precondition: Cache is already connected
def query_item_callback(key: str, arg: ncache.CQEventArg):
if arg.get_event_type() is ncache.EventType.ITEM_ADDED:
# Key has been added to the cache
print(key + " added to cache")
if arg.get_event_type() is ncache.EventType.ITEM_UPDATED:
# Key has been updated in the cache
# Get updated product object
if arg.get_item() is not None:
updated_product = arg.get_item().get_value(Product)
# Perform operations accordingly
if arg.get_event_type() is ncache.EventType.ITEM_REMOVED:
# key has been removed from the cache
print(key + " removed from cache")
Notes
Pour garantir la sécurité de l'opération, il est recommandé de gérer toutes les exceptions potentielles au sein de votre application, comme expliqué dans Gestion des échecs.
Étape 2 : enregistrer la requête et les notifications
Une fois les rappels enregistrés, créez une requête continue, qui spécifie les critères de l'ensemble de résultats dont les événements seront déclenchés. Cette requête sera enregistrée sur le serveur.
Une fois la requête continue créée, les rappels prédéfinis sont enregistrés avec la requête. Les rappels sont enregistrés selon EventType
ainsi que le EventDataFilter
.
La requête continue peut maintenant être enregistrée sur le serveur en utilisant RegisterCQ
. Vous pouvez utiliser cette méthode plusieurs fois dans votre application pour recevoir des notifications en cas de modification de l'ensemble de données de votre requête.
Toute modification des notifications d'événement de cache sera déclenchée en fonction du type d'événement. Pour interroger les données en cache, ExecuteReader
exécute la requête et l'ensemble de résultats généré est ensuite lu côté client, morceau par morceau.
Vous pouvez déclencher des événements en modifiant les données du cache de sorte qu'elles affectent le jeu de résultats. L'exemple de code met à jour un élément de cache existant de sorte qu'il soit ajouté au jeu de résultats de la requête, déclenchant ainsi un ItemAdded
un événement.
Si la connexion est interrompue entre un serveur et un client, les événements déclenchés pendant cette durée ne seront pas reçus par le client.
// Query for required operation
string query = "SELECT $VALUE$ FROM Alachisoft.NCache.Samples.Data.Product WHERE Category = ?";
// Create query command and add parameters
var queryCommand = new QueryCommand(query);
queryCommand.Parameters.Add("Category", "Beverages");
// Create Continuous Query
var cQuery = new ContinuousQuery(queryCommand);
// Item add, update, remove notification
// EventDataFilter.DataWithMetadata returns the cache keys added
cQuery.RegisterNotification(new QueryDataNotificationCallback(OnChangeInQueryResultSet), EventType.ItemAdded | EventType.ItemUpdated | EventType.ItemRemoved, EventDataFilter.DataWithMetadata);
// Register continuousQuery on server
cache.MessagingService.RegisterCQ(cQuery);
// Query for the desired operation
String query = "SELECT $VALUE$ FROM CQ.Product WHERE productId = ?";
// Create query command
QueryCommand queryCommand = new QueryCommand(query);
// Set parameters
HashMap<String, Object> parameters = queryCommand.getParameters();
parameters.put("productId", "Beverages");
// Create Continuous Query
ContinuousQuery cQuery = new ContinuousQuery(queryCommand);
// Register notifications for continuous query (ItemAdded, ItemUpdated, and ItemRemoved events)
cQuery.addDataModificationListener(new QueryDataModificationListener() {
@Override
public void onQueryDataModified(String key, CQEventArg arg) {
// Your callback method to handle the notifications
// For instance, you can call the 'onChangeInQueryResultSet' method from your earlier code here
onChangeInQueryResultSet(key, arg);
}
}, EnumSet.of(EventType.ItemAdded, EventType.ItemUpdated, EventType.ItemRemoved), EventDataFilter.DataWithMetadata);
// Register the continuous query on the server
cache.getMessagingService().registerCQ(cQuery);
System.out.println("Registered Successfully");
// Precondition: Cache is already connected
// Query for required operation
let query = "SELECT Values FROM FQN.Product WHERE Category = ?";
var queryCommand = new QueryCommand(query);
queryCommand.getParameters().put("Category", "Beverages");
// Create continuous query
let continuousQuery = new ncache.ContinuousQuery(queryCommand);
let listener = new ncache.EventFilter();
var eventType = ncache.EnumSet.of(ncache.EventType.ItemAdded, ncache.EventType.ItemRemoved, ncache.EventType.ItemUpdated);
// Item remove notification
// EventDataFilter.Metadata returns cache keys + item metadata on updation
continuousQuery.addDataModificationListener(listener, eventType, ncache.EventDataFilter.None);
// Register continuous query on server
await this.cache.getMessagingService().registerCQ(continuousQuery);
let reader = await this.cache.getSearchService().executeReader(queryCommand);
if (reader.getFieldCount() > 0)
{
while (reader.read())
{
let result = reader.getValue(1, Product);
// Perform operations
}
}
else
{
// Null query result set returned
}
// Update Product data in cache to trigger callback
let updatedProduct = new Product();
updatedProduct.setProductID(1001);
updatedProduct.setProductName("Tea");
let key = "Product:" + updatedProduct.getProductID();
let cacheItem = new ncache.CacheItem(updatedProduct);
// Trigger add notifications
let version = await this.cache.insert(key, cacheItem);
// This will add item to the result set as it matches query criteria
# Query for required operation
query = "SELECT $Value$ FROM FQN.Product WHERE category = ?"
query_command = ncache.QueryCommand(query)
query_command.set_parameters({"Category": "Beverages"})
# Create continuous query
continuous_query = ncache.ContinuousQuery(query_command)
event_type = [ncache.EventType.ITEM_REMOVED]
# Item remove notification
# EventDataFilter.Metadata returns cache keys + item metadata on updation
continuous_query.add_data_modification_listener(cq_event_listener, event_type, ncache.EventDataFilter.NONE)
# Register continuous query on server
cache.get_messaging_service().register_cq(continuous_query)
reader = cache.get_search_service().execute_reader(query_command)
if reader.get_field_count() > 0:
while reader.read():
result = reader.get_value(Product, 1)
# Perform operations
else:
# None query result set returned
print("Query result is None")
# Update Product data in cache to trigger callback
updated_product = Product()
updated_product.set_product_id(1001)
updated_product.set_product_name("Tea")
key = "Product:" + updated_product.get_product_id()
cache_item = ncache.CacheItem(updated_product)
# Trigger add notifications
version = cache.insert(key, cache_item)
# This will add item to the result set as it matches query criteria
Étape 3 : désinscrire les notifications de la requête continue
Les notifications peuvent être désenregistrées de la requête continue lorsqu'elles ne sont plus nécessaires dans l'application. Vous pouvez désenregistrer les notifications pour un type d'événement spécifique si plusieurs types d'événements ont été enregistrés à l'aide de l'icône UnRegisterNotification
méthode.
Par exemple, si ItemAdded
ainsi que le ItemRemoved
les types d'événements ont été enregistrés, mais votre logique métier ne nécessite plus d'événements pour ItemAdded
, vous pouvez spécifiquement annuler l'enregistrement des notifications pour ItemAdded
événements.
// Unregister notifications for ItemAdded events from continuous query
cQuery.UnRegisterNotification(new QueryDataNotificationCallback(OnChangeInQueryResultSet), EventType.ItemAdded);
// Unregister notifications for ItemAdded events only
cQuery.removeDataModificationListener(new QueryDataModificationListener() {
@Override
public void onQueryDataModified(String key, CQEventArg arg) {
// Your callback method to handle the notifications
// For instance, you can call the 'onChangeInQueryResultSet' method from your earlier code here
onChangeInQueryResultSet(key, arg);
}
}, EnumSet.of(EventType.ItemAdded, EventType.ItemUpdated, EventType.ItemRemoved));
// Unregister notifications for ItemAdded events only
var eventType = ncache.EnumSet.of(ncache.EventType.ADDED);
continuousQuery.removeDataModificationListener(listener, eventType);
# Unregister notifications for ItemAdded events only
event_type = [ncache.EventType.ITEM_ADDED]
c_query.remove_data_modification_listener(cq_event_listener, event_type)
Étape 4 : désinscrire la requête continue du serveur
Une fois que l'application n'est plus intéressée à recevoir des notifications pour les modifications apportées à un jeu de résultats de requête, la requête continue enregistrée doit être désenregistrée du serveur.
UnregisterCQ
prend comme argument un objet de ContinuousQuery
pour désenregistrer les rappels qui ne sont plus déclenchés après cet appel.
// Unregister Continuous Query from server
cache.MessagingService.UnRegisterCQ(cQuery);
// Unregister cq from server
cache.getMessagingService().unRegisterCQ(cQuery);
// Unregister cq from server
await this.cache.getMessagingService().unRegisterCQ(continuousQuery);
# Unregister cq from server
cache.get_messaging_service().un_register_cq(c_query)
Ressources additionnelles
NCache fournit un exemple d'application pour les requêtes continues sur GitHub.
Voir aussi
.RAPPORTER: Alachisoft.NCache.Runtime.Événements espace de noms.
Java: com.alachisoft.ncache.événements espace de noms.
Node.js : Requêtecontinue classe.
python: ncache.runtime.caching.events classe.