Erlang Mnesia эквивалент SQL выберите из поля где в (value1, value2, value3, …)

у меня есть таблица mnesia с полями, скажем f1, f2, f3. Теперь, если бы я выбрал все строки со значением поля как V1, я бы использовал mnesia:select и соответствуют спецификациям или простой mnesia:match_object. Теперь мне нужно выбрать все строки, которые имеют V1, V2, V3 ... или Vn (список произвольной длины) в качестве значения для поля f1. В SQL я бы сделал что-то вроде

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

как это сделать в мнезии?

3 ответов


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

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

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

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

ets:new(foo, [named_table]).

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

Vs = [a,c].

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

ets:select(foo, MS).

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

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

христианин указал, хорошее решение, но его можно сделать чуть проще

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

Так что для вас матч вы можете сделать проще матч spec

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}]

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

вы должны включите следующее, Так как оно включает преобразование parse, которое делает 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:select.