3

我在网上搜索了很多天,似乎互联网从未听说过我的问题:

我有一个包含英国大约 37M 条记录的邮政地址数据库表,它有一个地理空间索引和一个衍生的全文索引,如下所示:

create index on gb_locations using gin(to_tsvector('english', "Postcode" || ' ' || "Postcode_outcode" || ' ' || "Road" || ' ' || "Neighbourhood" || ' ' || "Admin2" || ' ' || "Admin3");)

我的全文搜索采用以下形式:

SELECT * FROM gb_locations
WHERE
    to_tsvector('english', "Postcode" || ' ' || "Postcode_outcode" || ' ' || "Road" || ' ' || "Neighbourhood" || ' ' || "Admin2" || ' ' || "Admin3") @@ plainto_tsquery('english', 'greenham road rg14')

该查询适用于大多数英国地址,尤其是在伦敦地区,但对于更远的位置,查询不会返回任何结果。

我已经验证该记录存在于表中,因为我可以使用地理空间搜索找到它,但对于全文搜索,数据库似乎不知道它。

这是解释:

Bitmap Heap Scan on gb_locations  (cost=52.04..56.10 rows=1 width=521)
  Recheck Cond: (to_tsvector('english'::regconfig, ((((((((((("Postcode")::text || ' '::text) || ("Postcode_outcode")::text) || ' '::text) || "Road") || ' '::text) || ("Neighbourhood")::text) || ' '::text) || ("Admin2")::text) || ' '::text) || ("Admin3")::text)) @@ '''greenham'' & ''road'' & ''rg14'''::tsquery)
  ->  Bitmap Index Scan on text_search_index  (cost=0.00..52.04 rows=1 width=0)
        Index Cond: (to_tsvector('english'::regconfig, ((((((((((("Postcode")::text || ' '::text) || ("Postcode_outcode")::text) || ' '::text) || "Road") || ' '::text) || ("Neighbourhood")::text) || ' '::text) || ("Admin2")::text) || ' '::text) || ("Admin3")::text)) @@ '''greenham'' & ''road'' & ''rg14'''::tsquery)

任何指针将不胜感激。

4

2 回答 2

5

如果某些字段可以为 NULL,则需要coalesce(field, '')在获取要搜索的字符串的全局串联中应用它们。

否则,它似乎适用于评论中给出的示例值:

select to_tsvector('english','RG147SW RG14 Greenham Road Newbury  West Berkshire')
  @@ plainto_tsquery('english', 'greenham road rg14');

 ?column? 
----------
 t
(1 row)

但是这个不匹配(结果为 NULL),当Admin2为 NULL 或更一般地任何其他字段按原样传递给||操作员时就是这种情况。

   select to_tsvector('english','RG147SW RG14 Greenham Road ' || NULL || ' Newbury  West Berkshire')
      @@ plainto_tsquery('english', 'greenham road rg14');

?column? 
----------

(1 row)
于 2012-12-08T15:08:28.973 回答
3

只是为了补充 Daniel Vérité 所说的,

如果任何字段预期为 NULL,则必须按如下方式创建全文索引:

create index [index name] on [table name] using gin(to_tsvector('english', coalesce("Field1",'') || ' ' || coalesce("Field2",'') || ' ' || coalesce("Field3",'') ....));

此外,查询本身必须使用相同的模板,如下所示:

SELECT * FROM [table name] WHERE to_tsvector('english', coalesce("Field1",'') || ' ' || coalesce("Field2",'') || ' ' || coalesce("Field3",'') ....) @@ plainto_tsquery('english', '[your search sentance/phrase]');
于 2012-12-08T15:30:18.203 回答