当前位置: 首页 > 知识库问答 >
问题:

最长前缀匹配

凤经武
2023-03-14

在PostgreSQL中获得最长前缀匹配的准确快速查询的最佳方法是什么?

是:

A.) select * from table where column in (subselect) ;

B.) select * from table where strpos(column,column2) = 1
    order by length(column2) desc limit 1 ;

C.) select * from table where column ~ column2
    order by length(column2) desc limit 1

我计划在更新中使用。有什么想法吗?

共有1个答案

吕英豪
2023-03-14

在PostgreSQL中,我不知道有哪一个函数可以开箱即用。
递归CTE是一个相当优雅的解决方案(可在PostgreSQL 8.4或更高版本中获得)的关键元素。

我假设有一个表filter来保存筛选字符串:

CREATE TABLE filter (f_id int, string text);

和要搜索最长匹配项的表TBL:

CREATE TABLE tbl(t_id int, col text);
WITH RECURSIVE
     f AS (SELECT f_id, string, length(string) AS flen FROM filter)
    ,t AS (SELECT t_id, col, length(col) AS tlen FROM tbl)
    ,x AS (
    SELECT t.t_id, f.f_id, t.col, f.string
          ,2 AS match, LEAST(flen, tlen) AS len
    FROM   t
    JOIN   f ON left(t.col, 1) = left(f.string, 1)

    UNION ALL
    SELECT t_id, f_id, col, string, match + 1, len
    FROM   x
    WHERE  left(col, match) = left(string, match)
    AND    match <= len
    )
SELECT DISTINCT
       f_id
      ,string
      ,first_value(col) OVER w AS col
      ,first_value(t_id) OVER w AS t_id
      ,(first_value(match) OVER w -1) AS longest_match
FROM   x
WINDOW w AS (PARTITION BY f_id ORDER BY match DESC)
ORDER  BY 2,1,3,4;

在相关答案中详细说明最终选择如何工作。
在SQLFiddle上的工作演示。

您没有定义要从一组相同长的匹配项中选择哪个匹配项。我从领带中挑出一个任意的赢家。

我计划在更新中使用。

PostgreSQL 9.1引入了修改CTE的数据,因此您可以直接在update语句中使用它。

 类似资料:
  • 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。 示例 1: 输入: ["flower","flow","flight"] 输出: "fl" 示例 2: 输入: ["dog","racecar","car"] 输出: "" 解释: 输入不存在公共前缀。 说明: 所有输入只包含小写字母 a-z 。 话不多说,上code: /** * @param {stri

  • 我有一个数组。在每个子数组中,如果两个或多个元素共享一个长度等于或大于8的前缀,那么我想用它们最长的前缀替换这些元素。对于此阵列: 我希望输出如下: 对于m中的第一个子数组,最长前缀为长度为9的974555899。 对于第二个子阵列,最长的前缀是长度为5的23480,长度小于8。在这种情况下,第二个子阵列保持原样。 对于此输入: 输出应如下所示: 对于数组m[0][code>,其四个数字之间没有足

  • foo-bar-herp foo-bar-derp baz-blub其他东西 我想提供一个搜索工作,以便 “foo bar”(标记化前缀) “Foo Herp”(跳过令牌) “foo-bar-”(确切的前缀) “bar-herp”(中间的确切字符串) “foo ba”(一个完整的令牌和另一个令牌的前缀) null

  • 我遇到了一个问题,elasticsearch在我的环境(舞台和生产)中返回不同的结果。 我使用的elasticsearch版本对于这两种环境是相同的。 这两个环境都具有相同的映射和索引设置。 我有一个项目索引的标题字段为“测试”。我正在尝试执行match_phrase_prefix查询。然而,在我的舞台环境中,当我搜索“te”时,结果会像预期的那样返回。在生产中,我必须将搜索查询扩展到“TES”(

  • 问题内容: 假设在我的Elasticsearch索引中,我有一个名为“点”的字段,其中将包含由标点符号分隔的字符串(例如“ first.second.third”)。 我需要搜索例如“ first.second”,然后获取其“点”字段包含正好是“ first.second”或以“ first.second”开头的字符串的所有条目。 我在理解文本查询的工作方式时遇到问题,至少我无法创建执行此任务的查

  • 我不知道如何通过MatchPhrasePrefix搜索索引中的文档。我想匹配整个搜索词短语,但允许在最后一个词上加前缀。 这个LINQ建筑给了我1.0分的一切。我将如何构建这个?另一方面,是否可以查看NEST正在构建的原始查询?那将非常有帮助!