Эквивалент SQL в Erlang Mnesia Select FROM WHERE Field IN (значение1, значение2, значение3,)

У меня есть таблица мнезии с полями, например, 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)

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


person ErJab    schedule 26.05.2010    source источник


Ответы (3)


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

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

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

Итак, давайте заполним таблицу ets чем-нибудь, чтобы попробовать это, а затем создадим спецификацию соответствия, которая сопоставляет только элементы со вторым элементом как '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}]
person Christian    schedule 26.05.2010

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

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}]
person Hynek -Pichi- Vychodil    schedule 01.06.2010
comment
Спасибо @Hynek -Pichi- Vychodil. Этот синтаксис erlang мне очень неприятен. Очень сложно понять новичкам - person Dr Deo; 13.11.2018

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

Вы должны иметь следующее включение, поскольку оно включает синтаксическое преобразование, которое делает возможным 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, встроенную в таблицу мнезии. Итак, ваш запрос может быть реализован следующим образом:

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.

person Christian    schedule 26.05.2010