【问题标题】:Parsing URLs in Postgres在 Postgres 中解析 URL
【发布时间】:2014-07-23 22:15:04
【问题描述】:

我在 Postgres 中解析 url 时遇到问题。我有一个充满客户和与他们相关联的网址的数据库。我需要一组与每个客户关联的唯一域。我希望能够在查询中进行解析,而不是将结果转储到 Python 并在那里解析。

在 postgres 文档中我找到了这个,但不知道如何将它合并到我的查询中:

SELECT alias, description, token FROM ts_debug('http://example.com/stuff/index.html');  

  alias   |  description  |            token               
----------+---------------+------------------------------  
 protocol | Protocol head | http://  
 url      | URL           | example.com/stuff/index.html  
 host     | Host          | example.com  
 url_path | URL path      | /stuff/index.html  

(http://www.postgresql.org/docs/9.3/static/textsearch-parsers.html)

我从一张桌子开始,像这样:

customer_id | url 
-------------+--------------------   
000001      | www.example.com/fish  
000001      | www.example.com/potato  
000001      | www.potato.com/artichoke
000002      | www.otherexample.com

到目前为止我的代码:

SELECT customer_id, array_agg(url)
FROM customer_url_table
GROUP BY customer_id

这给了我:

customer_id | unique_domains
-----------------------------
000001      | {www.example.com/fish, www.example.com/potato, www.potato.com/greenery}
000002      | {www.otherexample.com}

我想要一张这样的桌子:

customer_id | unique_domains
-----------------------------
000001      | {example.com, potato.com}
000002      | {otherexample.com}

使用 AWS 上的 PostgreSQL 9.3.3 数据库。

【问题讨论】:

  • 为什么在使用 9.3 版本时使用 8.3 版本的手册? 8.3 和 9.3 之间发生了很多变化
  • @frank-heikens,感谢您指出这一点。本文档中的相关部分在 9.3 和 8.3 中是相同的,所以我刚刚更新了链接以反映这一点。

标签: sql postgresql url-parsing


【解决方案1】:

您上面链接的文档用于Postgres 文本搜索解析器。这需要单独的配置来设置,并且可能比您正在寻找的开销更大和/或不同类型的东西。

如果您确实想走这条路,设置文本解析器,您可以在此处找到更多信息:

http://www.postgresql.org/docs/9.3/static/sql-createtsconfig.html

但是,如果您想在 Postgres 中进行内联解析,我建议您使用过程式 Postgres 语言,您可以在其中导入该语言的解析库。

您提到了 Python,因此您可以使用 PL/Python 和诸如 urlparse 之类的 url 解析库(称为 urllib.在 Python 3 中解析)。

More info about urlparse

包括此示例代码:

>>> from urlparse import urlparse
>>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
>>> o   
ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> o.scheme
'http'
>>> o.port
80
>>> o.geturl()
'http://www.cwi.nl:80/%7Eguido/Python.html'

超越该示例,您可以使用 hostname 成员获取主机名:

>>> print o.hostname
www.cwi.nl

如果您只想正确解析域名(有很多边缘情况和变体 - 即减去 www 和可能存在的任何其他分类部分 - 一种方法,例如this answer 最好。

关于设置PL/Python的更多信息,你可以去这里:

http://www.postgresql.org/docs/9.3/static/plpython.html

所以,这就是您可以在 Postgres

中进行解析的方式

而不是将我的结果转储到 Python 并在那里解析

PL/Python 的结果有点绕圈子,但如果您真的想在 SQL 中进行解析(尤其是出于性能原因,例如,跨大型数据集),使用 PL/Python 可能值得付出额外的努力。

【讨论】:

  • 是的,这也是我的建议。如果性能至关重要,您可以改为编写一个简单的 C 扩展来包装一个 C 库,该库执行 URL 解析并从中返回结果集,但这需要更多的工作。
  • 谢谢,这真的很有帮助。我不知道 PL/Python 是一回事。我一直在寻找一个关于创建函数和执行一般 SQL 脚本的不错的教程,但我没有成功。
猜你喜欢
  • 1970-01-01
  • 2013-12-08
  • 2011-10-02
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多