2014-07-27 35 views
1

對於初學者來說,一個小圖的關係,實體

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:

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; 

我做的關鍵字一個連接,它是這個原因使得它慢!但我找不到另一種解決方案。

回答

0

我認爲問題是用距離計算進行完全連接。這是另一種方法。首先篩選關鍵字。通過使用子查詢將信息保留在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 
+0

非常感謝您的幫助。這個查詢更有效率。但我無法解決我最後的問題。 對於我來說,重視包含兩個搜索關鍵字的存檔是一個謎。 如果您知道在X搜索關鍵字存檔時添加更多價值的想法嗎? – cjnet

+0

@cjnet。 。 。你是否試過用poid desc命令? –

+0

是的,但是使用關鍵字的權重是爲了在搜索歸檔文件時賦予其重要性和含義。但是,在第一個位置包含X搜索關鍵字的檔案不起作用。自5天以來,我在這個查詢中出現了一個空白,現在我再也無法對這個問題有一個客觀的看法。 – cjnet