【问题标题】:Search entities by weighted keywords and spelling correction通过加权关键字和拼写更正搜索实体
【发布时间】:2014-09-18 18:07:27
【问题描述】:

对于初学者来说,关系实体的小图

Diagram relations-entities http://img11.hostingpics.net/pics/32979039DB.png

现在,一个数据集

存档

创建:

CREATE TABLE archive (
    id integer NOT NULL,
    parent_id integer,
    code character varying(15) NOT NULL,
    label text NOT NULL
);

ALTER TABLE ONLY archive ADD CONSTRAINT archive_pkey PRIMARY KEY (id);

CREATE INDEX idx_142 ON archive USING btree (parent_id);

CREATE UNIQUE INDEX uniq_14242 ON archive USING btree (code);

ALTER TABLE ONLY archive ADD CONSTRAINT fk_14242 FOREIGN KEY (parent_id) REFERENCES archive(id);

插入:

INSERT INTO archive VALUES (1, NULL, 'B28',   'Confidential');
INSERT INTO archive VALUES (2, 1,    'B28.0', 'Nuclear zone');

关键字

创建:

CREATE TABLE keyword (
    id integer NOT NULL,
    label text NOT NULL,
    label_double_metaphone text NOT NULL
);

ALTER TABLE ONLY keyword ADD CONSTRAINT eyword_pkey PRIMARY KEY (id);

CREATE UNIQUE INDEX uniq_242 ON keyword USING btree (label);

插入:

INSERT INTO keyword VALUES (1, 'SECURITY', 'SKRT');
INSERT INTO keyword VALUES (2, 'AREA',     'AR');
INSERT INTO keyword VALUES (3, 'NUCLEAR',  'NKLR');

Assoc_kw_archive

创建:

CREATE TABLE assoc_kw_archive (
    id integer NOT NULL,
    keyword_id integer,
    archive_id integer,
    weight integer NOT NULL
);


ALTER TABLE ONLY assoc_kw_archive ADD CONSTRAINT assoc_kw_archive_pkey PRIMARY KEY (id);

CREATE INDEX idx_3421 ON assoc_kw_archive USING btree (archive_id);

CREATE INDEX idx_3422 ON assoc_kw_archive USING btree (keyword_id);

ALTER TABLE ONLY assoc_kw_archive ADD CONSTRAINT fk_3421 FOREIGN KEY (archive_id) REFERENCES archive(id);

ALTER TABLE ONLY assoc_kw_archive ADD CONSTRAINT fk_3422 FOREIGN KEY (keyword_id) REFERENCES keyword(id);

插入:

INSERT INTO assoc_kw_archive VALUES (1, 1, 1, 10);
INSERT INTO assoc_kw_archive VALUES (2, 1, 2, 20);
INSERT INTO assoc_kw_archive VALUES (3, 2, 2, 30);
INSERT INTO assoc_kw_archive VALUES (4, 3, 2, 30);

目标

这里的目标是在数据库中搜索。该研究基于用户键入的字符串。输出按相关性排序的档案列表。相关存档取决于三个因素:

  1. 人们可能会在单词拼写等方面犯错...
  2. 一个词的重要性赋予它的重要性
  3. 让档案中包含用户输入的 x 关键字

我处理过不同版本的 sql 查询,但是,现在我不能退后一步来看看整体问题。

存档表由 100,000 个元组、80,000 个关键字表和这两个实体之间的 1,000,000 个关联组成。

这是我的最后一个版本,她可以正常工作,但速度很慢:

select f.id, f.code, f.label, min(f.dist) as distF, max(f.poid) as poidF
from
(
    select
        a.id,
        a.code,
        a.label,
        ( ( levenshtein(lower('Security'), lower(k1.label)) + 1 ) + ( levenshtein(lower('Nuclear'), lower(k2.label)) + 1 ) ) as dist,
        ( ka1.weight + ka2.weight ) as poid

    from archive a

    inner join assoc_kw_archive ka1
        on ka1.archive_id = a.id
    inner join keyword k1
        on k1.id = ka1.keyword_id

    inner join assoc_kw_archive ka2
        on ka2.archive_id = a.id
    inner join keyword k2
        on k2.id = ka2.keyword_id

    where levenshtein(dmetaphone('Security'), k1.label_double_metaphone) < 2
      and levenshtein(dmetaphone('Nuclear'), k2.label_double_metaphone) < 2
) as f

group by f.id, f.code, f.label
order by distF asc, poidF desc
limit 10;

我用关键字做了一个连接,就是这个让它变慢了!但我找不到其他解决方案。

【问题讨论】:

    标签: sql postgresql search full-text-search postgresql-9.3


    【解决方案1】:

    我认为问题在于使用距离计算进行完全连接。这是另一种方法。先过滤关键词。使用子查询将信息保留在where 子句中。然后使用条件聚合来获取你想要的信息。

    查询最终看起来像:

    select a.id, a.code, a.label,
           min( (levenshtein(lower('Security'), lower(case when securityl < 2 then k.label end)) + 1 ) +
                (levenshtein(lower('Nuclear'), lower(case when nuclearl < 2 then k.label end)) + 1 )
              ) as mindist,
           sum(weight) as poid
    from archive a inner join
         assoc_kw_archive ka
         on ka.archive_id = a.id inner join
         (select k.*, levenshtein(dmetaphone('Security'), k.label_double_metaphone) as securityl,
                 levenshtein(dmetaphone('Nuclear'), k.label_double_metaphone)  as nuclearl
          from keyword k
          having securityl < 2 or
                 nuclearl < 2
         ) k
         on k.id = ka.keyword_id
    group by a.id, a.code, a.label
    

    【讨论】:

    • 非常感谢您的帮助。这个查询效率更高。但我无法解决我的最后一个问题。对包含两个搜索关键字的存档给予重视对我来说是一个谜。如果您知道当 X 个搜索关键字在存档中时增加更多价值的想法?
    • @cjnet 。 . .你试过order by poid desc吗?
    • 是的,但是关键字的权重用于在搜索档案时赋予其重要性和意义。但是,包含 X 搜索关键字的存档在第一位,不起作用。自 5 天以来,我在这个查询上一直处于空白状态,现在我不再能够对这个问题有客观的看法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多