Java 电话号码前缀查找

Java 电话号码前缀查找,java,postgresql,jdbc,lookup,prefix,Java,Postgresql,Jdbc,Lookup,Prefix,我必须实现基于java的呼叫路由引擎,它根据电话号码前缀将呼叫路由到适当的网关 这里是我的表(postgres),包含前缀: CREATE TABLE call_routing ( prefix character varying(20) PRIMARY KEY NOT NULL, carrier character varying(50) NOT NULL, dialstring character varying(50) NOT NULL ) 一些样本数据: INSERT IN

我必须实现基于java的呼叫路由引擎,它根据电话号码前缀将呼叫路由到适当的网关

这里是我的表(postgres),包含前缀:

CREATE TABLE call_routing (
  prefix character varying(20) PRIMARY KEY NOT NULL,
  carrier character varying(50) NOT NULL,
  dialstring character varying(50) NOT NULL
)
一些样本数据:

INSERT INTO call_routing values ('02','1','/sofia/gateway/gw1');
INSERT INTO call_routing values ('0221','1','/sofia/gateway/gw2');
INSERT INTO call_routing values ('0228','1','/sofia/gateway/gw3');
例如,电话号码0221123456789应发送至网关“/sofia/gateway/gw2”,电话号码0211123456789应发送至“/sofia/gateway/gw1”等

问题:

  • 使用java/jdbc查询最佳匹配前缀的最快方法是什么
  • 在应用程序启动时将表读入java对象,并在每次调用时不访问db的情况下用java执行所有操作,这是一种更好的方法吗

  • 我个人会缓存该表,但您可以通过按长度排序获得最佳匹配前缀(
    number
    是您要搜索的):


    我个人会缓存该表,但您可以通过按长度排序获得最佳匹配前缀(
    number
    是您要搜索的):


    我想知道这件事。看起来最大的问题是您有catchalls(在您的示例中是gw1)


    索引这将是困难的,但我想第一个问题是,你在跟踪多少个呼叫前缀?

    我想知道这一点。看起来最大的问题是您有catchalls(在您的示例中是gw1)


    建立索引将很困难,但我想第一个问题是,您要跟踪多少个呼叫前缀?

    获取更好的索引

    通过直接按前缀而不是长度(前缀)排序:

    为什么?

    因为数字
    abcdef
    的选定行将是前缀。以下数字也是如此:

    a ab abc abcd

    所以,如果你按字母顺序排列,就足以得到一个从最长到最短的列表,这就是你想要的

    此外,您还可以使用以下方法获得更强的过滤器:


    介于'a'和'abcde'之间的前缀
    。所有前缀将按字母顺序
    =
    最短前缀,并按字母顺序
    获得更好的索引

    通过直接按前缀而不是长度(前缀)排序:

    为什么?

    因为数字
    abcdef
    的选定行将是前缀。以下数字也是如此:

    a ab abc abcd

    所以,如果你按字母顺序排列,就足以得到一个从最长到最短的列表,这就是你想要的

    此外,您还可以使用以下方法获得更强的过滤器:


    介于'a'和'abcde'之间的前缀
    。您的所有前缀将按字母顺序
    =
    最短前缀,按字母顺序
    您还可以在github上查看此PostgreSQL模块,该模块专门用于为电话号码提供快速前缀匹配:
    

    您还可以在github上查看此PostgreSQL模块,该模块专门用于为电话号码提供快速前缀匹配:

    数据库只包含2位或4位前缀数字?或者更多,更少?前缀可以是2到7位。数据库只包含2位或4位前缀数字?或者更多,更少?前缀可以是2到7个数字,我认为应该是:从call_routing中选择dialstring,其中strpos(数字,前缀)=1 ORDER BY length(前缀)DESC LIMIT 1;您是否有建议如何索引该表以获得该查询的最佳性能?我认为应该是:从call_routing中选择dialstring,其中strpos(number,prefix)=1 ORDER BY length(prefix)DESC LIMIT 1;您对如何索引表以使该查询具有最佳性能有何建议?我将您的查询与David的查询进行了比较,这两个查询在我的环境中都在44毫秒内执行,调用路由表中有1538个条目。由于只有1538个条目,我认为在内存中缓存是更好的方法,但是当有更改时,我必须重新加载表。是的。确实值得缓存。如果您想缓存,请看:它具有我提到的树结构。我将您的查询与David的查询进行了比较,两个查询都在44毫秒内在我的环境中执行,调用路由表中有1538个条目。由于只有1538个条目,我认为在内存中缓存是更好的方法,但是当有更改时,我必须重新加载表。是的。如果你想缓存,看看:它有我提到的树结构。
    SELECT dialstring FROM call_routing WHERE strpos(number, prefix) = 1 ORDER BY length(prefix) DESC LIMIT 1;
    
    SELECT dialstring from call_routing where number like prefix || '%'
    ORDER BY length(prefix) DESC
    LIMIT 1
    
    SELECT dialstring FROM call_routing
    WHERE number like prefix || '%'
    ORDER BY prefix DESC
    LIMIT 1
    
    SELECT dialstring FROM call_routing WHERE
    prefix between substr(number, 1, 1) and number -- range filter (use index)
    AND number like prefix || '%' -- only relevant data (normal filter)
    ORDER BY prefix DESC -- index will work
    LIMIT 1
    
    be
    b
    abcde
    abbbc
    abd
    ab
    
    - you find a prefix (OK, this is the winner)
    - it doesn't start with the same char (there are no prefix)
    
    0 // represents 0
     ->
       2  // represents 02
         -> 1 // represents 021
         -> 3 // represents 023
     ->
       4 // represents 04
    
    Node n = root;
    for (char c: number) {
        if ((child = n.hasChild(c)) != null)
        {
           prefix += c;
           n = child;
        }
        else
           break;
    }
    
    class Node
    {
       int digit;
       Map<Integer, Node> childs = new HashMap<Integer, Node>(); // or a 10 bucket array :)
       YourInfo info;
    }
    
    findOrCreateNode(prefix).setInfo(info);