2017-01-14 5 views
1

мне нужно сгруппировать Mnesia записей по sender_id, вот запись:Как группировать объекты по идентификатору возвращаемых Mnesia: функция match_object

-record(pm,{sender_id, recipient_id, msg, time}). 

в основном мне нужно, чтобы извлечь все записи, где recipient_id=X и сгруппировать их по sender_id

Что это самый быстрый способ сделать это?

Ситуация очевидна и ясна, я думаю.

+0

Какую версию Erlang вы используете? – Stratus3D

ответ

2

Существует несколько способов решить эту проблему.

Получить результаты и сортировать их по sender_id

Это, безусловно, самым простым решением. Просто получить результат (список записей), как обычно и sort the records по sender_id:

lists:sort(fun(A, B) -> 
    A#pm.sender_id < B#pm.sender_id 
end, Results). 

Использование QLC: фолд/3

Это немного сложнее, но это, кажется, немного более элегантный, используя простой старый lists:sort/2. Вместо того, чтобы возвращать список, он возвращает dict.

select_grouped_pms_for_recipient(RecipientId) -> 
    Q = qlc:q([E || E <- mnesia:table(pm), E#pm.recipient_id == RecipientId]), 
    qlc:fold(fun group/2, dict:new(), Q). 

group(Record, Acc) -> 
    dict:append(Record#pm.sender_id, Record, Acc). 

В функции group/2 мы помещаем запись на список значений для ID отправителя в dict аккумулятора. select_grouped_pms_for_recipient/1 вернет полученный dict список всех записей, сгруппированных под ключами идентификатора отправителя.

В списке рассылки Erlang есть сокровищница хороших вопросов и ответов. Я нашел this question в списке рассылки, который очень похож на ваш вопрос.

Который быстрее?

Глядя на эти решения, я не уверен, что будет большая разница в производительности. Я думаю, что они примерно одинаковы, но с qlc блокировка сохраняется во время всей логики группировки для каждого полученного элемента, поэтому он может удерживать блокировку Mnesia немного дольше.