2010-07-31 11 views
6

Ich habe eine Tabelle in meinem DB mit einer freien Textfeld Spalte.Berechne TF-IDF mit Sql

Ich möchte die Häufigkeit wissen, mit der jedes Wort über alle Zeilen erscheint, oder vielleicht sogar eine TF-IDF für alle Wörter berechnen, wobei meine Dokumente die Werte dieses Feldes pro Zeile sind.

Ist es möglich, dies mit einer SQL-Abfrage zu berechnen? Wenn nicht oder es gibt einen einfacheren Weg, könnten Sie mich bitte dazu bringen?

Vielen Dank,

Jon

+0

Was RDBMS und Version? –

+0

Microsoft SQL Server 2008 – Jon

Antwort

5

In SQL Server 2008 je nach Bedarf können Sie die Volltextindizierung anwenden an die Spalte dann die sys.dm_fts_index_keywords und sys.dm_fts_index_keywords_by_documenttable valued functions abfragen, um die Anzahl der Vorkommen zu erhalten.

Edit: Eigentlich auch ohne eine dauerhafte Volltextindex zu erstellen, können Sie immer noch nutzen, der Parser

WITH testTable AS 
(
SELECT 1 AS Id, N'how now brown cow' AS txt UNION ALL 
SELECT 2, N'she sells sea shells upon the sea shore' UNION ALL 
SELECT 3, N'red lorry yellow lorry' UNION ALL 
SELECT 4, N'the quick brown fox jumped over the lazy dog' 
) 

SELECT display_term, COUNT(*) As Cnt 
FROM testTable 
CROSS APPLY sys.dm_fts_parser('"' + REPLACE(txt,'"','""') + '"', 1033, 0,0) 
WHERE TXT IS NOT NULL 
GROUP BY display_term 
HAVING COUNT(*) > 1 
ORDER BY Cnt DESC 

Returns

display_term     Cnt 
------------------------------ ----------- 
the       3 
brown       2 
lorry       2 
sea       2 
+0

Sie rocken !!! Das ist eine erstaunliche Lösung, für die ich Tage gebraucht hätte. (Ich musste nur eine Zeile hinzufügen, um Felder mit Null-Text zu filtern, sonst würde es einen Fehler "Null oder leeres Volltext-Prädikat" zurückgeben, die Zeile, die ich hinzufüge, war "WHERE tbl1.txt_field! = '"' '') – Jon

+0

Danke, ich werde das in meine Antwort integrieren. –

2

Lösung für SQL Server 2008:

hier ist die Tabelle:

CREATE TABLE MyTable (id INT, txt VARCHAR(MAX)); 

hier ist SQL-Abfrage:

SELECT sum(case when TSplitted.txt_word = 'searched' then 1 else 0 end) as cnt_searched 
    , count(*) as cnt_all 
FROM MyTable MYT 
INNER JOIN Fn_Split(MYT.id,' ',MYT.txt) TSplitted on MYT.id=TSplitted.id 

hier ist Tabellenwertfunktion Fn_Split (@id int, @separator VARCHAR (32), @string VARCHAR (MAX)) (aus here):

CREATE FUNCTION Fn_Split (@id int, @separator VARCHAR(32), @string VARCHAR(MAX)) 

RETURNS @t TABLE 
    (
     ret_id INT 
     ,txt_word VARCHAR(MAX) 
    ) 
AS 
    BEGIN 
     DECLARE @xml XML 
     SET @XML = N'<root><r>' + REPLACE(@s, @separator, '</r><r>') + '</r></root>' 

     INSERT INTO @t(ret_id, val) 
     SELECT @id, r.value('.','VARCHAR(5)') as Item 
     FROM @xml.nodes('//root/r') AS RECORDS(r) 

     RETURN 
    END