Question

Je travaille actuellement sur une application où nous avons une base de données SQL-Server et j'ai besoin de faire fonctionner une recherche en texte intégral qui nous permet de rechercher les noms des personnes.

Actuellement, l'utilisateur peut saisir un champ de nom qui recherche 3 colonnes varchar différentes.Prénom, nom, deuxième prénom

Disons donc que j'ai 3 lignes avec les informations suivantes.

1 - Phillip - J - Fry

2 - Amy - NULL - Wong

3 - Lion - NULL - Wong

Si l'utilisateur saisit un nom tel que « Fry », il renverra la ligne 1.Cependant, s'ils entrent dans Phillip Fry, Fr ou Phil, ils n'obtiennent rien.et je ne comprends pas pourquoi il fait ça.S'ils recherchent Wong, ils obtiennent les lignes 2 et 3. S'ils recherchent Amy Wong, ils n'obtiennent rien.

Actuellement, la requête utilise CONTAINSTABLE mais j'ai changé cela avec FREETEXTTABLE, CONTAINS et FREETEXT sans aucune différence notable dans les résultats.Les méthodes de table sont à privilégier car elles renvoient les mêmes résultats mais avec classement.

Voici la requête.

....
@Name nvarchar(100),
....
--""s added to prevent crash if searching on more then one word.
DECLARE @SearchString varchar(100)
SET @SearchString = '"'+@Name+'"'
SELECT Per.Lastname, Per.Firstname, Per.MiddleName
FROM Person as Per
INNER JOIN CONTAINSTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) 
AS KEYTBL
ON Per.Person_ID = KEYTBL.[KEY]
WHERE KEY_TBL.RANK > 2
ORDER BY KEYTBL.RANK DESC;  
....

Des idées...?Pourquoi cette recherche en texte intégral ne fonctionne pas correctement ?

Était-ce utile?

La solution 3

Merci pour vos réponses les gars, j'ai enfin pu le faire fonctionner.Avec une partie des réponses de Biri et de Kibbee.J'avais besoin d'ajouter * à la chaîne et de la diviser en espaces pour fonctionner.Donc à la fin j'ai eu

....
@Name nvarchar(100),
....
--""s added to prevent crash if searching on more then one word.
DECLARE @SearchString varchar(100)

--Added this line
SET @SearchString = REPLACE(@Name, ' ', '*" OR "*')
SET @SearchString = '"*'+@SearchString+'*"'

SELECT Per.Lastname, Per.Firstname, Per.MiddleName
FROM Person as Per
INNER JOIN CONTAINSTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) 
AS KEYTBL
ON Per.Person_ID = KEYTBL.[KEY]
WHERE KEY_TBL.RANK > 2
ORDER BY KEYTBL.RANK DESC;  
....

Il y a plus de champs recherchés, je l'ai juste simplifié pour la question, désolé, je ne pensais pas que cela affecterait la réponse.Il recherche en fait une colonne contenant un csv de surnoms et une colonne de notes également.

Merci pour l'aide.

Autres conseils

FreeTextTable devrait fonctionner.

INNER JOIN FREETEXTTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) 

@SearchString doit contenir des valeurs telles que « Phillip Fry » (une longue chaîne contenant toutes les chaînes de recherche séparées par des espaces).

Si vous souhaitez rechercher Fr ou Phil, vous devez utiliser un astérisque :Phil* et Fr*

« Phil » recherche exactement le mot « Phil ».'Phil*' recherche tous les mots commençant par 'Phil'

Si vous recherchez uniquement les noms de personnes, il peut être dans votre intérêt de ne même pas utiliser l'index de texte intégral.L'index de texte intégral a du sens lorsque vous disposez de grands champs de texte, mais si vous traitez principalement un mot par champ, je ne suis pas sûr de la quantité supplémentaire que vous obtiendriez des index de texte intégral.Attendre que l'index de texte intégral se réindexe avant de pouvoir rechercher de nouveaux enregistrements peut être l'un des nombreux problèmes.

Vous pouvez simplement faire une requête telle que la suivante.Divisez votre chaîne de recherche en espaces et créez une liste des termes de recherche.

Select FirstName,MiddleName,LastName 
From person 
WHERE 
Firstname like @searchterm1 + '%'
or MiddleName like @searchterm1 + '%'
or LastName like @searchterm1 + '%'
or Firstname like @searchterm2 + '%'
etc....

Une autre approche pourrait consister à faire abstraction de la recherche des domaines individuels.

En d'autres termes, créez une vue sur vos données qui transforme tous les champs fractionnés comme le prénom et le nom en champs concaténés, c'est-à-direnom et prénom

Recherchez ensuite sur la vue.Cela simplifierait probablement la requête de recherche.

Vous voudrez peut-être vérifier Lucène.net comme alternative au texte intégral.

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