Java 电话号码前缀查找
我必须实现基于java的呼叫路由引擎,它根据电话号码前缀将呼叫路由到适当的网关 这里是我的表(postgres),包含前缀: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
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”等
问题:
我个人会缓存该表,但您可以通过按长度排序获得最佳匹配前缀(
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);