2010-05-26 4 views
6

У меня есть таблица mnesia с полями, скажем f1, f2, f3. Теперь, если бы я должен был выбрать все строки с значением поля как V1, я бы использовал mnesia:select и спецификации соответствия или простой mnesia:match_object. Теперь мне нужно выбрать все строки с V1, V2, V3 ... или Vn (список произвольной длины) в качестве значения для поля f1. В SQL я бы сделал что-то вродеErlang Mnesia Эквивалент SQL Select FROM WHERE Поле IN (value1, value2, value3, ...)

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

Как это сделать в mnesia?

ответ

5

И для решения этой проблемы, если QLC измеряется как недостаточно эффективный.

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

ГЭ: fun2ms является синтаксическое преобразование, которое может перевести некоторые потех Into matchspec значения. Я использую его как быстрый способ получить matchspec, который я хочу. Мы получаем список с matchspec, который находит кортеж, где вторым элементом является a. Мы можем повторить его для других ключей.

Так что давайте заполнить таблицу ets, чтобы попробовать это, а затем создать matchspec, который соответствует только элементам со вторым элементом как 'a' или 'c'. (Я войти в этот

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). 

Когда я запускаю это я получаю:

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

Если вам нужны «сложные» запросы, то QLC является кратким способом их описания. QLC - это синтаксический анализ, который позволяет использовать синтаксис понимания списка в разных таблицах, включая таблицы mnesia.

У вас must есть следующие включенные, так как он позволяет преобразование синтаксического анализа, которое делает QLC возможным в этом исходном файле.

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

Основная форма запроса выглядит следующим образом, создавая дескриптор запроса и затем оценивая запрос.

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

Вы можете использовать http://www.erlang.org/doc/man/mnesia.html#table-1 приобрести QLC таблицу обратно состава в таблице Mnesia. Таким образом, ваш запрос может быть реализован следующим образом:

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

Для этого требуется сканирование таблицы, которое не очень эффективно. Если у вас есть индекс в столбце f3, вы можете вместо этого повернуть его и сначала запросить записи с помощью f3 = V1, затем V2 и т. Д., И слить результаты.

PS

Альтернативой является создание достаточно сложный матч-спецификации из вашего списка V-значений и запустить Mnesia: выберите.

3

Christian отметил красивое решение, но оно может быть немного проще

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

так для вас сопрягать вас может упростить соответствие спецификации

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}] 
Смежные вопросы