全文检索&使用PostgreSQL进行模糊搜索

时间:2014-07-04 13:57:13

标签: php postgresql laravel pattern-matching

如果这是一个愚蠢的问题,请原谅我。

我的一次迁移中有以下代码:

    DB::statement("
    CREATE MATERIALIZED VIEW searchable_stores AS
    SELECT
    chain_stores.id as chain_store_id,
    local_chain_stores.id as local_chain_store_id,
    chain_stores.website as website,
    chain_stores.name as name,
    chain_stores.cname as cname,
    chain_stores.flyer_url as flyer_url,
    local_chain_stores.city as city,
    local_chain_stores.shopping_mall as shopping_mall,
    local_chain_stores.postal_code as postal_code,
    local_chain_stores.street_address as street_address,
    to_tsvector('sv', chain_stores.name) ||
    to_tsvector('sv', replace(chain_stores.name, ' ', '')) ||
    to_tsvector('sv', local_chain_stores.city) ||
    to_tsvector('simple', to_char(local_chain_stores.postal_code, '99999')) ||
    to_tsvector('sv', coalesce(local_chain_stores.shopping_mall)) ||
    to_tsvector('sv', local_chain_stores.street_address) ||
    to_tsvector('sv', chain_stores.bio)
    as document
    FROM
        local_chain_stores, chain_stores
    WHERE
        local_chain_stores.chain_store_id = chain_stores.id
    ");

这就是我查询表格的方式:

    $results = SearchableStore::
        whereRaw("document @@ plainto_tsquery('simple', ?)", array($searchQuery->getQuery()))
        ->orWhereRaw("document @@ plainto_tsquery('sv', ?)", array($searchQuery->getQuery()))
        ->orderBy('name', 'asc')
        ->get();
    return $results;

这非常合适,除非有人说错了一些字。这就是我想要解决的问题。您还会注意到这两行:

    to_tsvector('sv', chain_stores.name) ||
    to_tsvector('sv', replace(chain_stores.name, ' ', '')) ||

我知道这很难看,但我基本上做的是确保如果有人搜索“BurgerKing”,我想返回“汉堡王”的结果。我知道这看起来像一个愚蠢的例子,但这些错误在瑞典语中发生了很多(不一定是汉堡王,但其他条款)。除此之外,我还想确保当有人打错字时我仍然希望返回相关结果。

所以,我的问题是。我该如何实现?我尝试使用模糊搜索,但我有点卡住,因为我不知道如何查询由tsvector值组成的列(文档)。

2 个答案:

答案 0 :(得分:3)

Full Text Search适用于字典和词干,不适合模糊搜索和一般模式匹配 考虑额外的模块pg_trgm。它的运算符类允许支持LIKE的GIN或GiST索引以及相关的模式匹配运算符。

此相关答案的详情:
PostgreSQL LIKE query performance variations

Postgres中模式匹配技术概述:
Pattern matching with LIKE, SIMILAR TO or regular expressions in PostgreSQL

答案 1 :(得分:1)

你要找的是同义词和同义词词典,编译它们需要做很多工作,但是在CPU和磁盘使用方面会使你的搜索更具成本效益。

对于某些语言,您可以找到可以在OpenOffice中轻松转换为您自己的其他语言的词库词典。我仍然在寻找好的消息来源,并在此发表了一个关于此主题的问题:https://dba.stackexchange.com/questions/80632/where-to-download-dutch-postgresql-fulltext-search-dictionaries,到目前为止还没有答案。

如果您正在运行Linux,那么安装您的语言的myspell或hunspell软件包也是值得的。有关安装这些软件包的信息,请参阅:https://askubuntu.com/questions/72099/how-to-install-a-libreoffice-dictionary-spelling-check-thesaurus

如果您想知道如何在PostgreSQL中使用它们,您应该阅读有关配置全文搜索的内容,我真的很喜欢这个人,因为这里以轻松易懂的方式撰写文章:a full text search engine