2008-10-14 10 views
12

मैं एक एसक्यूएल बैकएंड के साथ एक सी #/एएसपी.NET ऐप बना रहा हूं। मैं समय सीमा पर हूं और अपने पृष्ठों को खत्म कर रहा हूं, बाएं क्षेत्र से बाहर मेरे डिजाइनरों में से एक ने मेरे पृष्ठों में से एक पर एक पूर्ण पाठ खोज शामिल की है। इस बिंदु तक मेरी "खोज" तब तक फ़िल्टर की गई है, जो कुछ कारकों और कॉलम मानों द्वारा निर्धारित परिणाम को संकीर्ण करने में सक्षम है।SQL सर्वर के साथ पूर्ण पाठ खोज को शामिल करना कितना मुश्किल है?

ऐसा होने के नाते कि मैं समय सीमा पर हूं (आपको पता है कि रात में 3 घंटे सोते हैं, उस बिंदु पर जहां मैं बिल्ली खा रहा था और फेंक दिया था), मैं उम्मीद कर रहा था कि यह पृष्ठ दूसरों के समान ही होगा और मैं यह तय करने की कोशिश कर रहा हूं कि क्या बदबू आ रही है या नहीं। मैंने पहले कभी एक पृष्ठ पर पूर्ण पाठ खोज नहीं की है .... क्या यह चढ़ाई करने वाला पहाड़ है या क्या कोई आसान समाधान है?

धन्यवाद।

उत्तर

27

सबसे पहले, आप अनुक्रमण सर्च कर रहे हैं पूर्ण पाठ सक्षम करने की आवश्यकता है उत्पादन सर्वर पर, इसलिए यदि यह दायरे में नहीं है, तो आप इसके साथ नहीं जाना चाहते हैं।

हालांकि, अगर यह पहले से ही तैयार है, तो पूर्ण पाठ खोज अपेक्षाकृत सरल है।

T-SQL 4 पूर्ण पाठ खोज के लिए इस्तेमाल किया विधेय है:

  • FREETEXT
  • FREETEXTTABLE
  • शामिल हैं
  • CONTAINSTABLE

FREETEXT सरल है, और किया जा सकता है इस तरह:

SELECT UserName 
FROM Tbl_Users 
WHERE FREETEXT (UserName, 'bob') 

Results: 

JimBob 
Little Bobby Tables 

FREETEXTTABLE फ्रीTEXT के समान काम करता है, सिवाय इसके कि यह परिणाम तालिका के रूप में देता है।

T-SQL का पूर्ण पाठ खोज की वास्तविक शक्ति आता है (और CONTAINSTABLE) विधेय से ... यह एक बहुत बड़ा है, तो मैं बस में इसके उपयोग चस्पा करेंगे:

CONTAINS 
    ({ column | * } , '<contains_search_condition>' 
    ) 

<contains_search_condition> ::= 
     { <simple_term> 
     | <prefix_term> 
     | <generation_term> 
     | <proximity_term> 
     | <weighted_term> 
     } 
     | { (<contains_search_condition>) 
     { AND | AND NOT | OR } <contains_search_condition> [ ...n ] 
     } 

<simple_term> ::= 
    word | " phrase " 

< prefix term > ::= 
    { "word * " | "phrase * " } 

<generation_term> ::= 
    FORMSOF (INFLECTIONAL , <simple_term> [ ,...n ]) 

<proximity_term> ::= 
    { <simple_term> | <prefix_term> } 
    { { NEAR | ~ } { <simple_term> | <prefix_term> } } [ ...n ] 

<weighted_term> ::= 
    ISABOUT 
     ({ { 
       <simple_term> 
       | <prefix_term> 
       | <generation_term> 
       | <proximity_term> 
       } 
      [ WEIGHT (weight_value) ] 
      } [ ,...n ] 
     ) 

यह साधन आप इस तरह के रूप प्रश्नों लिख सकते हैं:

SELECT UserName 
FROM Tbl_Users 
WHERE CONTAINS(UserName, '"little*" NEAR tables') 

Results: 

Little Bobby Tables 

गुड लक :)

+4

मैंने इसे वोट दिया है और इसे न केवल उत्तर के रूप में छोड़ दिया है क्योंकि यह एक महान और विस्तृत प्रतिक्रिया है, लेकिन xkcd संदर्भ के लिए भी। जीत। –

0

"यह कितना मुश्किल है" जवाब देने का एक कठिन सवाल है। उदाहरण के लिए, कोई भी जो इसे पहले से 10 बार कर चुका है, शायद यह एक स्नैप मान लेगा। मैं वास्तव में कह सकता हूं कि अगर आप NLucene जैसे कुछ स्वयं का उपयोग करने के बजाय कुछ उपयोग करते हैं तो आपको यह बहुत आसान लगता है।

2

SQL सर्वर में पूर्ण पाठ खोज वास्तव में आसान है, कॉन्फ़िगरेशन का थोड़ा सा है और क्वेरीसाइड पर थोड़ा सा झटका है और आप जाने के लिए अच्छे हैं! मैंने पहले 20 मिनट के अंदर ग्राहकों के लिए यह किया है, प्रक्रिया

यहाँ 2008 MSDN article है से परिचित होने के नाते, लिंक वहाँ से 2005 संस्करण के लिए बाहर जाना

2

मैंने पहले फ़ाइलों और डेटाबेस के लिए खोज पूरा टेक्स्ट जोड़ने के लिए dtSearch का इस्तेमाल किया है, और उनके सामान बहुत सस्ते और आसान टी है ओ उपयोग करें।

एसक्यूएल को कॉन्फ़िगर करने और कॉन्फ़िगर करने के लिए, यह स्क्रिप्ट डेटाबेस में सभी कॉलमों के माध्यम से खोज करेगी और आपको बताएगी कि कौन से कॉलम आप देख रहे हैं।मैं इसे "उचित" समाधान नहीं जानता, लेकिन आपको कुछ समय खरीद सकता है।

/*This script will find any text value in the database*/ 
/*Output will be directed to the Messages window. Don't forget to look there!!!*/ 

SET NOCOUNT ON 
DECLARE @valuetosearchfor varchar(128), @objectOwner varchar(64) 
SET @valuetosearchfor = '%staff%' --should be formatted as a like search 
SET @objectOwner = 'dbo' 

DECLARE @potentialcolumns TABLE (id int IDENTITY, sql varchar(4000)) 

INSERT INTO @potentialcolumns (sql) 
SELECT 
    ('if exists (select 1 from [' + 
    [tabs].[table_schema] + '].[' + 
    [tabs].[table_name] + 
    '] (NOLOCK) where [' + 
    [cols].[column_name] + 
    '] like ''' + @valuetosearchfor + ''') print ''SELECT * FROM [' + 
    [tabs].[table_schema] + '].[' + 
    [tabs].[table_name] + 
    '] (NOLOCK) WHERE [' + 
    [cols].[column_name] + 
    '] LIKE ''''' + @valuetosearchfor + '''''' + 
    '''') as 'sql' 
FROM information_schema.columns cols 
    INNER JOIN information_schema.tables tabs 
     ON cols.TABLE_CATALOG = tabs.TABLE_CATALOG 
      AND cols.TABLE_SCHEMA = tabs.TABLE_SCHEMA 
      AND cols.TABLE_NAME = tabs.TABLE_NAME 
WHERE cols.data_type IN ('char', 'varchar', 'nvchar', 'nvarchar','text','ntext') 
    AND tabs.table_schema = @objectOwner 
    AND tabs.TABLE_TYPE = 'BASE TABLE' 
ORDER BY tabs.table_catalog, tabs.table_name, cols.ordinal_position 

DECLARE @count int 
SET @count = (SELECT MAX(id) FROM @potentialcolumns) 
PRINT 'Found ' + CAST(@count as varchar) + ' potential columns.' 
PRINT 'Beginning scan...' 
PRINT '' 
PRINT 'These columns contain the values being searched for...' 
PRINT '' 
DECLARE @iterator int, @sql varchar(4000) 
SET @iterator = 1 
WHILE @iterator <= (SELECT Max(id) FROM @potentialcolumns) 
BEGIN 
    SET @sql = (SELECT [sql] FROM @potentialcolumns where [id] = @iterator) 
    IF (@sql IS NOT NULL) and (RTRIM(LTRIM(@sql)) <> '') 
    BEGIN 
     --SELECT @sql --use when checking sql output 
     EXEC (@sql) 
    END 
    SET @iterator = @iterator + 1 
END 

PRINT '' 
PRINT 'Scan completed' 
1

मैं वहां गया हूं। यह एक आकर्षण की तरह काम करता है जब तक आप स्केलेबिलिटी और उन्नत खोज कार्यक्षमताओं पर विचार करना शुरू करते हैं जैसे कि एकाधिक कॉलम पर खोज करने के साथ-साथ कई अलग-अलग वजन मान भी देते हैं।

उदाहरण के लिए, से अधिक शीर्षक और सारांश कॉलम खोज करने के लिए एक ही रास्ता SearchColumn = CONCAT(Title, Summary) और SearchColumn से अधिक सूचकांक के साथ एक गणना स्तंभ है। भार? SearchColumn = CONCAT(CONCAT(Title,Title), Summary) ऐसा कुछ। ;) फ़िल्टरिंग? इसके बारे में भूल जाओ।

संबंधित मुद्दे