Question

Je construis une application C # / ASP.NET avec un moteur SQL. Je suis dans les délais et je termine mes pages; en dehors du champ gauche, l'un de mes concepteurs a incorporé une recherche de texte intégral sur l'une de mes pages. Mes " recherches " jusqu’à présent, des filtres permettent de restreindre un résultat défini par certains facteurs et valeurs de colonne.

Étant donné que je suis sur la date limite (vous savez 3 heures de sommeil par nuit, au moment où je ressemble à quelque chose que le chat a mangé et vomi), je m'attendais à ce que cette page ressemble beaucoup aux autres et je 'essaie de décider si oui ou non de faire une puanteur. Je n'ai jamais fait de recherche de texte intégral sur une page auparavant ... est-ce une montagne à gravir ou une solution simple?

merci

Était-ce utile?

La solution

Tout d'abord, vous devez activer la recherche en texte intégral dans l'indexation sur les serveurs de production. Par conséquent, si ce n'est pas dans la portée, vous ne voudrez plus y aller.

Toutefois, si cela est déjà prêt, la recherche en texte intégral est relativement simple.

T-SQL a 4 prédicats utilisés pour la recherche en texte intégral:

  • FREETEXT
  • FREETEXTTABLE
  • CONTIENT
  • CONTAINSTABLE

FREETEXT est le plus simple, et peut être fait comme ceci:

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

Results:

JimBob
Little Bobby Tables

FREETEXTTABLE fonctionne de la même manière que FreeTEXT, sauf qu'il renvoie les résultats sous forme de tableau.

Le véritable pouvoir de la recherche en texte intégral de T-SQL provient du prédicat CONTAINS (et CONTAINSTABLE) ... Celui-ci est énorme, je vais donc coller son utilisation dans:

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 ] 
        ) 

Cela signifie que vous pouvez écrire des requêtes telles que:

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

Results:

Little Bobby Tables

Bonne chance:)

Autres conseils

La recherche de texte intégral dans SQL Server est très facile, un peu de configuration et une légère modification du côté de la requête et vous êtes prêt à partir! Je l'ai fait pour les clients en moins de 20 minutes auparavant, étant familiarisé avec le processus

Voici le article de MSDN 2008 , des liens vers les versions 2005 à partir de là

J’avais déjà utilisé dtSearch pour ajouter de la recherche en texte intégral à des fichiers et à des bases de données, et leur contenu est relativement peu coûteux et facile à utiliser.

À part l'ajout de tout cela et la configuration de SQL, ce script va parcourir toutes les colonnes d'une base de données et vous indiquer quelles colonnes contiennent les valeurs que vous recherchez. Je sais que ce n'est pas le "bon" solution, mais peut vous faire gagner du temps.

/*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'

J'y suis allé. Cela fonctionne comme un charme jusqu'à ce que vous commenciez à envisager l'évolutivité et des fonctionnalités de recherche avancées telles que la recherche sur plusieurs colonnes en donnant à chacune une valeur de poids différente.

Par exemple, la seule façon de rechercher dans les colonnes Titre et Résumé consiste à disposer une colonne calculée avec SearchColumn = CONCAT (Titre, Résumé) et indexez sur SearchColumn . Pondération? SearchColumn = CONCAT (CONCAT (titre, titre), résumé) quelque chose comme ça. ;) Filtrage? Oubliez ça.

"Comment est-ce difficile?" est une question difficile à répondre. Par exemple, quelqu'un qui l'a déjà fait 10 fois va probablement penser que c'est un jeu d'enfant. Tout ce que je peux vraiment dire, c’est que vous trouverez probablement cela beaucoup plus facile si vous utilisez quelque chose comme NLucene plutôt que de rouler vous-même.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top