J'espère que je ne répète pas cette question. J'ai fait quelques recherches ici et google avant de poster ici.
J'utilise un eStore avec SQL Server 2008R2 avec le texte intégral activé.
J'utilise un Fulltext hybride et j'aime faire une recherche normale. Cela donne des résultats plus pertinents. Toutes les requêtes exécutées dans une table temporaire et distinctes ont été renvoyées.
Logique de correspondance,
Exécutez le SQL suivant pour obtenir le produit pertinent en utilisant le texte intégral. Mais @Keywords sera prétraité. Dites "CLC 2200" sera changé en "CLC * ET 2200 *"
SELECT Id FROM dbo.Product WHERE CONTAINS (TextSearch, @ Keywords)
Une autre requête s'exécutera en utilisant normal like. Ainsi, "CLC 2200" sera prétraité en "TextSearch comme% clc% ET TextSearch comme% 2200%". C'est simplement parce que la recherche en texte intégral ne recherchera pas les modèles avant les mots clés. par exemple, il ne renverra pas 'pclc 2200'.
SELECT ID FROM dbo.Product WHERE TextSearch like '% clc%' AND TextSearch like '% 2200%'
Si les étapes 1 et 2 n'ont renvoyé aucun enregistrement, la recherche suivante sera exécutée. La valeur 135 a été affinée par moi pour renvoyer des enregistrements plus pertinents.
SELECT p.id FROM dbo.Product AS p INNER JOIN FREETEXTTABLE (produit, TextSearch, @ Keywords) AS r ON p.Id = r. [KEY] WHERE r.RANK> 135
Tous les éléments combinés ci-dessus fonctionnent correctement à une vitesse raisonnable et renvoient des produits pertinents pour les mots clés.
Mais je cherche à m'améliorer encore quand aucun produit n'est trouvé.
Dites si le client recherche "CLC 2200npk" et que ce produit n'était pas là, je devais le montrer très près de "CLC 2200".
Jusqu'à présent, j'ai essayé d'utiliser la fonction Soundex () . Achetez la valeur soundex informatique pour chaque mot dans la colonne TextSearch et comparez avec la valeur soudex du mot clé. Mais cela renvoie beaucoup trop d'enregistrements et ralentit aussi.
exemple, 'CLC 2200npk' renverra des produits tels que 'CLC 1100' etc. Mais ce ne serait pas un bon résultat. Comme il n'est pas proche du CLC 2200npk
Il y en a un autre bon ici . mais cela utilise les fonctions CLR. Mais je ne peux pas installer les fonctions CLR sur le serveur.
Donc ma logique devrait être,
si 'CLC 2200npk' non trouvé, montrer à côté de 'CLC 2200' si 'CLC 2200' non trouvé, montrer à côté de 'CLC 1100'
Merci.
Une solution spécifique au domaine plutôt rapide peut être de calculer une similitude de chaîne à l'aide de SOUNDEX et une distance numérique entre 2 chaînes. Cela ne vous sera vraiment utile que si vous avez beaucoup de codes de produit.
En utilisant un UDF simple comme ci-dessous, vous pouvez extraire les caractères numériques d'une chaîne de sorte que vous puissiez ensuite obtenir 2200 de 'CLC 2200npk' et 1100 de 'CLC 1100' afin que vous puissiez maintenant déterminer la proximité en fonction de la sortie SOUNDEX de chaque entrée ainsi que la proximité de la composante numérique de chaque entrée.
CREATE Function [dbo].[ExtractNumeric](@input VARCHAR(1000))
RETURNS INT
AS
BEGIN
WHILE PATINDEX('%[^0-9]%', @input) > 0
BEGIN
SET @input = STUFF(@input, PATINDEX('%[^0-9]%', @input), 1, '')
END
IF @input = '' OR @input IS NULL
SET @input = '0'
RETURN CAST(@input AS INT)
END
GO
En ce qui concerne les algorithmes à usage général, il en existe quelques-uns qui pourraient vous aider avec plus ou moins de succès en fonction de la taille de l'ensemble de données et des exigences de performances. (les deux liens ont des implémentations TSQL disponibles)
Ici est un article intéressant qui applique les deux algos ensemble, ce qui peut vous donner quelques idées.
Et bien, j'espère que cela aide un peu.
EDIT: ici est une implémentation partielle beaucoup plus rapide de la distance de Levenshtein (lire l'article qui ne renverra pas exactement les mêmes résultats que celui normal). Sur ma table de test de 125 000 lignes, il s'exécute en 6 secondes, contre 60 secondes pour la première à laquelle je suis lié.