基于SQL索引的搜索

时间:2016-11-20 10:09:02

标签: sql postgresql search indexing

我有一个名为Index的表,其中包含idvalue列,其中id是自动增量bigint,value是varchar用英文单词。

我有一个名为Search的表,它与表Index有关系。对于每个搜索,您可以在名为Article的表中定义应搜索的索引。

表格Article也与表格Index有关系。

定义关系的表是:

Searches_Indexesid_searchid_index

Articles_Indexesid_articleid_index

我想查找包含相同搜索索引的所有文章。

例如:我有Search索引laptopdell,我想检索包含两个索引的所有Article,而不只是一个。< / p>

到目前为止,我有这个:

SELECT ai.id_article 
FROM articles_indexes AS ai 

INNER JOIN searches_indexes AS si 
ON si.id_index = ai.id_index 

WHERE si.id_search = 1

如何让我的SQL仅返回Article以及Index的所有Search个?

修改

示例数据:

文章:

id | name          | description           | ...
1  | 'Dell Laptop' | 'New Dell Laptop...'  | ...
2  | 'HP Laptop'   | 'Unused HP Laptop...' | ...
...

搜索:

id | name                 | id_user | ...
1  | 'Dell Laptop Search' | 5       | ...

索引:

id | value
1  | 'dell'
2  | 'laptop'
3  | 'hp'
4  | 'new'
5  | 'unused'
...

Articles_Indexes:

<{1}} Article 1(戴尔笔记本电脑)有id es'dell','笔记本电脑','新'。

Index Article 2(hp笔记本电脑)有id es'笔记本电脑','hp','未使用'。

Index

Searches_Indexes:

id_article | id_index 1 | 1 1 | 2 1 | 4 ... 2 | 2 2 | 3 2 | 5 ... 1的

Search仅包含2个id es,'dell'和'laptop':

Index

必填项:

id_search | id_index
1         | 1
1         | 2

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您需要聚合和HAVING子句。假设索引表中没有重复的条目:

SELECT ai.id_article 
FROM articles_indexes ai INNER JOIN
     searches_indexes si 
     ON si.id_index = ai.id_index 
WHERE si.id_search = 1
GROUP BY ai.id_article
HAVING COUNT(*) = (SELECT COUNT(*) FROM searches_indexes si2 WHERE si2.id_search = 1);

这会计算匹配数,并确保匹配您要查找的数字。

我应该补充一下。如果您想同时查找所有搜索,我倾向于将其写为:

SELECT si.id_search, ai.id_article 
FROM articles_indexes ai INNER JOIN
     (SELECT si.*, COUNT(*) OVER (PARTITION BY si.id_index) as cnt
      FROM searches_indexes si 
     ) si
     ON si.id_index = ai.id_index 
GROUP BY si.id_search, ai.id_article, si.cnt
HAVING COUNT(*) = si.cnt;

答案 1 :(得分:0)

您可以比较数组。这是一些例子:

create table article_index(id_article int, id_index int);
create table search_index(id_search int, id_index int);

insert into article_index
select generate_series(1,2), generate_series(1,10);
insert into search_index
select generate_series(1,2), generate_series(1,4);

select 
    id_article
from article_index
group by id_article
having array_agg(id_index) @> (select array_agg(id_index) from search_index where id_search = 2);

Learn more关于postgres中的数组。