Search code examples
databasedistributed

How to access individual "columns" from retrieved element?


Is there any way to retrieve an element from an ETS table and acces, say column 1, without inserting the object into the ETS as a record?

The only place I have seen similar syntax, to refer to each column is with the '$1' on the match arguments.


Solution

  • Assuming you have the following:

    1> ets:new(people, [set, named_table]).
    2> ets:insert(people, {silvio, italy, joker}).
    3> ets:insert(people, {roberto, italy, employee}).
    

    (Note I'm adding a generic tuple to the table - a record is simply a tuple where the first element is the name of the record itself and you have some syntactic sugar to access the records' elements -)

    You could do the following 'match' operation:

    4> ets:match(people, {'$1', 'italy', '_'}).
    

    Which means:

    Match all entries made of three columns, where the second element is the atom 'italy'. Discard the third argument, since I'm only interested into the first one.

    This would return:

    [[silvio],[roberto]]
    

    Alternatively, you could perform the following 'select' operation:

    5> ets:select(people, [{{'$1', '$2', '$3'},
                           [{'==', '$2', italy}],
                           [['$3']]}]).
    

    Which means:

    Select on all the entries made of three 'columns', where the second element is equal to 'italy', returning the third element only.

    In your case, that would return:

    [[joker],[employee]]
    

    Bare in mind that the match operations, to be really efficient, have been implemented as BIFs, so they will stop other processes while executing. This means that, for large table, you should look at other mechanisms, such as "traversing an ETS table".