2010-05-26 6 views
6

J'ai une table mnesia avec les champs disons f1, f2, f3. Maintenant, si je devais sélectionner toutes les lignes avec la valeur du champ que V1, j'utiliserais mnesia:select et les spécifications de correspondance ou un simple mnesia:match_object. Maintenant, j'ai besoin de sélectionner toutes les lignes qui ont V1, V2, V3 ... ou Vn (une liste de longueur arbitraire) comme valeur pour le champ f1. Dans SQL je ferais quelque chose commeErlang Mnesia Équivalent de SQL Select FROM WHERE Champ IN (valeur1, valeur2, valeur3, ...)

SELECT * FROM tablename WHERE f3 IN (V1, V2, V3, ... , Vn) 

Comment puis-je faire en mnesia?

Répondre

5

Et pour la solution match-spec à ce problème, si QLC est mesurée comme pas assez efficace.

> ets:fun2ms(fun ({_,X}=E) when X == a -> E end). 
[{{'_','$1'},[{'==','$1',a}],['$_']}] 

l'ÉTS: fun2ms est une Parse transformation qui peut traduire quelques funs en valeurs matchspec. Je l'utilise comme un moyen rapide d'obtenir le matchspec que je veux. Nous obtenons une liste avec un matchspec qui trouve un tuple où le second élément est a. Nous pouvons le répéter pour d'autres clés.

Nous allons donc remplir une table ets avec quelque chose à essayer, puis créer une correspondance match qui ne correspond qu'aux éléments ayant un second élément comme 'a' ou 'c'. (J'entre ce

ets:new(foo, [named_table]). 

ets:insert(foo, [{1,a},{2,b},{3,c},{4,d}]). 

Vs = [a,c]. 

MS = [{{'_','$1'},[{'==','$1',V}],['$_']} || V <- Vs]. 

ets:select(foo, MS). 

Quand je lance ce que je reçois:

[{1,a},{3,c}] 
2

Si vous avez besoin de requêtes "complexes", alors QLC est un moyen succinct de les énoncer. QLC est une transformation d'analyse qui vous permet d'utiliser la syntaxe de compréhension de liste sur diverses tables, y compris les tables Mnesia.

Vous devez inclure inclure, car il permet la transformation d'analyse qui rendent possible QLC dans ce fichier source.

-include_lib("stdlib/include/qlc.hrl"). 

La forme de requête de base est la suivante, en créant un handle de requête, puis en évaluant la requête.

QH = qlc:q([X || X <- Xs]), 
qlc:eval(QH). 

Vous pouvez ensuite utiliser http://www.erlang.org/doc/man/mnesia.html#table-1 pour acquérir une table CTQ retour à composition non limitée dans une table de mnesia. Ainsi, votre requête pourrait être mis en œuvre comme suit:

Vs = [V1,V2,...Vn], 
QH = qlc:q([X || X <- mnesia:table(tablename), 
       lists:member(X#tablename.f3, Vs)]), 
qlc:eval(QH). 

Cela nécessite une table-scan, ce qui est très efficace. Si vous avez un index sur la colonne f3 alors vous pouvez le retourner et interroger d'abord les entrées avec f3 = V1, puis V2, etc, ... et fusionner les résultats.

PS

Une alternative est de créer un match spec assez complexe de votre liste de valeurs V et exécuter mnesia: sélectionnez.

3

Christian fait remarquer belle solution, mais il peut être fait peu plus simple

2> ets:fun2ms(fun ({_,a}=E) -> E end).    
[{{'_',a},[],['$_']}] 

si vous vous correspondez peut rendre les spécifications de correspondance plus simples

4> ets:new(foo, [named_table]). 
foo 
5> ets:insert(foo, [{1,a},{2,b},{3,c},{4,d}]). 
true 
6> Vs = [a,c]. 
[a,c] 
7> MS = [{{'_',V},[],['$_']} || V <- Vs].     
[{{'_',a},[],['$_']},{{'_',c},[],['$_']}] 
8> ets:select(foo, MS). 
[{1,a},{3,c}] 
Questions connexes