web-dev-qa-db-fra.com

Requête utilisant plusieurs conditions

J'ai récemment découvert (malheureusement) que WebSQL n'est plus pris en charge pour HTML5 et que IndexedDB le remplacera à la place.

Je me demande s'il existe un moyen d'interroger ou de rechercher dans les entrées d'un IndexedDB d'une manière similaire à la façon dont je peux utiliser SQL pour rechercher une entrée remplissant plusieurs conditions.

J'ai vu que je peux rechercher dans IndexedDB en utilisant une condition avec KeyRange. Cependant, je n'arrive pas à trouver un moyen de rechercher deux ou plusieurs colonnes de données sans saisir toutes les données de la base de données et le faire avec des boucles.

Je sais que c'est une nouvelle fonctionnalité qui est à peine implémentée dans les navigateurs, mais j'ai un projet que je démarre et je recherche les différentes façons de le faire.

Je vous remercie!

33
jthereliable

Découvrez cette réponse à la même question. Elle est plus détaillée que la réponse que je donne ici. Le paramètre keypath pour les méthodes store.createIndex et IDBKeyRange peut être un tablea . Donc, exemple brut:

// In onupgradeneeded
var store = db.createObjectStore('mystore');
store.createIndex('myindex', ['prop1','prop2'], {unique:false});

// In your query section
var transaction = db.transaction('mystore','readonly');
var store = transaction.objectStore('mystore');
var index = store.index('myindex');
// Select only those records where prop1=value1 and prop2=value2
var request = index.openCursor(IDBKeyRange.only([value1, value2]));
// Select the first matching record
var request = index.get(IDBKeyRange.only([value1, value2]));
29
Josh

Disons que votre requête SQL est quelque chose comme:

SELECT * FROM TableName WHERE Column1 = 'value1' AND Column2 = 'value2'

Requête équivalente dans la bibliothèque JsStore :

var Connection = new JsStore.Instance("YourDbName");
Connection.select({
    From: "YourTableName"
    Where: {
        Column1: 'value1',
        Column2: 'value2'
    },
    OnSuccess:function (results){
        console.log(results);
    },
    OnError:function (error) {
        console.log(error);
    }
});

Maintenant, si vous vous demandez ce qu'est JsStore, laissez-moi vous dire que c'est une bibliothèque pour interroger IndexedDB de manière simplifiée. Cliquez ici pour en savoir plus sur JsStore

3
user6422990

J'ai quelques années de retard, mais je voudrais juste souligner que la réponse de Josh fonctionne sur la présomption que toutes les "colonnes" de la condition font partie du keyPath de l'index.

Si l'une des dites "colonnes" existe en dehors du keyPath de l'index, vous devrez tester les conditions les impliquant sur chaque entrée sur laquelle le curseur créé dans l'exemple itère. Donc, si vous avez affaire à de telles requêtes, ou si votre index n'est pas unique, préparez-vous à écrire du code d'itération!

Dans tous les cas, je vous suggère de vérifier BakedGoods si vous pouvez représenter votre requête comme une expression booléenne.

Pour ces types d'opérations, il ouvrira toujours un curseur sur le ObjectStore focal sauf si vous effectuez une requête d'égalité stricte (x ===? y, étant donné que x est un objectStore ou une clé d'index), mais cela vous évitera d'avoir à écrire votre propre code d'itération du curseur:

bakedGoods.getAll({
    filter: "keyObj > 5 && valueObj.someProperty !== 'someValue'",
    storageTypes: ["indexedDB"],
    complete: function(byStorageTypeResultDataObj, byStorageTypeErrorObj){}
});

Dans un souci de transparence totale, BakedGoods est maintenu par moi .

1
Kevin

Oui, l'ouverture d'une plage de clés continue sur un index est à peu près celle qui est dans indexedDB. Le test de condition multiple n'est pas possible dans IndexedDB. Cela doit être fait sur la boucle du curseur.

Si vous trouvez la solution, faites-le moi savoir.

BTW, je pense que le curseur en boucle pourrait être très rapide et nécessiter moins de mémoire que possible avec Sqlite.

1
Kyaw Tun

Je mentionne quelques suggestions pour interroger les relations dans ma réponse à cette question, qui peuvent être intéressantes:

Problèmes conceptuels avec IndexedDB (relations, etc.)

En ce qui concerne l'interrogation de plusieurs champs à la fois, il ne semble pas qu'il y ait une façon native de le faire dans IndexedDB (je peux me tromper; je suis encore nouveau), mais vous pouvez certainement créer une fonction d'assistance qui utilise une autre curseur pour chaque champ, et itéré sur eux pour voir quels enregistrements répondaient à tous les critères.

0
Matt Browne