【问题标题】:Elixir searching an ETS tableElixir 搜索 ETS 表
【发布时间】:2021-12-21 15:35:45
【问题描述】:

我有一些元组存储在 Elixir :ets 表中,格式如下,

{id, "first_name", "last_name"}

在给定搜索词的情况下,我正在搜索 ETS 表中的名字和姓氏。例如,如果某人的名字是 Alice,则搜索将返回此元组“Al”、“Ali”、“Alic”等。

到目前为止我已经尝试过:

:ets.match_object(table_name, {:_, :_, "last_name"})

当它与“last_name”完全匹配时有效,但如果我在搜索字符串中有“last”或更短的排列,它不会返回结果。

我还研究了搜索向量、ets.match、ets.lookup 和其他一些执行搜索的方法。是否有一些内置的或其他 Elixiry 方法来进行这种类型的字符串搜索?

【问题讨论】:

    标签: elixir ets


    【解决方案1】:

    请记住,您在 Erlang 中有通用比较规则,这意味着您可以比较字符串 "Alice" 和 "Al",因为它们只是列表。

    现在进入有趣的部分:

    table = :ets.new(:table, [:protected, :set])
    
    :ets.insert(table, {1, "Alice", "Dannings"})
    :ets.insert(table, {2, "Ali", "Aaqib"})
    :ets.insert(table, {3, "Bob", "Dannings"})
    :ets.insert(table, {4, "Amanda", "Clarke"})
    :ets.insert(table, {5, "Al", "Clarke"})
    
    # now let's explore elixir comparison rules
    
    "Alice" >= "Al"
    "Alice" < "Am"
    
    # based on rules above we can make a selector which will be equivalent to starts_with?
    
    selector = :ets.fun2ms(
      fn({_, x, _} = y) # match all three element tuples
        when # where
           x >= "Al" and x < "Am"   # second element is greater or equal to "Al" and less than "Am" ("m" is the next letter in the alphabet)
         -> y end)
    
    :ets.select(table, selector)
    
    #[{1, "Alice", "Dannings"}, {2, "Ali", "Aaqib"}, {5, "Al", "Clarke"}]
    
    

    虽然你可以通过字符串的开头“搜索”,但这很 hacky。

    如果您想在运行时使用它,您必须在模块开头设置@compile {:parse_transform, :ms_transform} 或使用https://github.com/ericmj/ex2ms 之类的库来确保正确生成匹配规范(选择器)。

    【讨论】:

    【解决方案2】:

    人们可能会使用ets 查找、:ets.foldl/3 的瑞士刀。

    :ets.foldl(fn
      {_, "Al" <> _, _} = y, acc -> [y | acc] # firstname
      {_, _, "Al" <> _} = y, acc -> [y | acc] # lastname
      _, acc -> acc                           # no match
    end, [], table)
    

    请注意,与@MikhailAksenov 提出的解决方案相比,这效率较低,因为搜索是在调用过程中完成的,因此所有数据都必须在那里传输,而不是在ets“内部”进行过滤.

    【讨论】:

      猜你喜欢
      • 2017-10-17
      • 2016-03-21
      • 2012-02-07
      • 2019-02-05
      • 2019-06-11
      • 1970-01-01
      • 1970-01-01
      • 2020-11-12
      • 2016-06-03
      相关资源
      最近更新 更多