Question

J'ai une base de données remplie d'enregistrements remplis de caractères asiatiques (chinois, japonais et coréen) ainsi que de ceux contenant des enregistrements remplis de caractères latins (anglais, français, # 231; ais, comme vous l'appelez), et je souhaite exécuter le texte intégral. recherches sur eux.

MySQL dit:

  

Langues idéographiques telles que le chinois   et les japonais n'ont pas mot   les délimiteurs. Par conséquent, le FULLTEXT   analyseur ne peut pas déterminer où les mots   commencer et se terminer dans ceux-ci et d'autres tels   langues. Les implications de cette   et quelques solutions de contournement pour le problème   sont décrits à la section 11.8,   & # 8220; Fonctions de recherche de texte intégral & # 8221;.

La section 11.8 n'offre pas de solution de rechange ni même de mentionner le problème.

Alors, comment trieriez-vous la recherche d'un seul caractère chinois dans une base de données contenant plusieurs caractères ? % LIKE% fonctionnerait, mais il n'a pas les notations de pertinence astucieuses. Devrais-je simplement compter le nombre de fois qu'un personnage apparaît dans l'enregistrement et le classer par celui-ci? J'apprécie tous les conseils que vous avez. Merci!

Était-ce utile?

La solution

Cela dépend de la taille du jeu de données. Si nous parlons de centaines de milliers de lignes, je regarderais probablement l'une des excellentes solutions de recherche en texte intégral indépendantes disponibles. En fait, je n'ai jamais eu à traiter ce problème avec mysqlf, je ne sais donc pas quelles solutions incluent la prise en charge des langues asiatiques.

Je sais cependant que lucene arbore un analyseur pour le chinois, le japonais et le coréen. qu'il a une sorte de soutien pour ce que vous faites. Ce que je fais habituellement lorsque je dois intégrer lucene à php, c’est que j’implémente lucene en tant que serveur de socket et que je me connecte à partir de php.

Si le jeu de données est suffisamment petit, vous pouvez éventuellement utiliser votre propre approche ad-hoc. Ce problème comporte deux parties: la récupération des documents à classer et le classement actuel. Il y a plusieurs façons de récupérer les données. On pourrait utiliser LIKE, si votre jeu de données est suffisamment petit. Une autre solution consisterait à déployer votre propre schéma d’indexation basé sur disque, bien que cela soit plutôt complexe et prendrait beaucoup de temps. Vous pouvez également utiliser MySQL comme chemin intermédiaire, comme décrit ci-dessous.

Pour implémenter un schéma d'indexation avec MySQL, vous devez créer quelques tables avec la structure suivante:

document
  document_id
  document_text
  document_tokencount

document_token
  document_id
  token_id
  token_docfrequency
  index (token_id, document_id)

token
  token_id
  token_unicode
  token_globalfrequency
  index (token_unicode)

Ensuite, je traiterais chaque document et insérerais une ligne dans la table document_token pour chaque caractère (jeton) du document. Le champ token_unicode contiendrait la séquence unicode entière utilisée pour faire référence à ce caractère. Le champ token_docfrequency contient un entier correspondant au nombre de fois que le document contient le jeton, tandis que le champ token_globalfrequency contient le nombre total d'utilisations du terme, dans tous les documents.

Cela vous permettrait d'effectuer des recherches rapides de jetons:

SELECT * FROM document_token WHERE token_id = 1
UNION
SELECT * FROM document_token WHERE token_id = 2
UNION
SELECT * FROM document_token WHERE token_id = 3

(l'approche de l'union est un hack qui permet à mysql d'utiliser des index pour tous les sélections, et sera probablement plus rapide que la requête correspondante utilisant une seule sélection et plusieurs ou déclarations)

Cela nous laisse avec le classement par pertinence comme problème restant, ce que vous avez réellement demandé. :) Ceci peut être obtenu avec de bons résultats en utilisant le modèle d'espace vectoriel (VSM) .

Après avoir effectué une recherche, la première chose à faire est de calculer le tf-idf marquer pour ce jeton. Ceci est fait en utilisant la formule:

tf-idf = tf(t,d) / tf(d) * log(D / d(t))

where:
tf(t,d) = token frequency in current document
tf(d) = total number of tokens in current document
D = total number of documents
d(t) = number of document that contains the token

Commencez par calculer ce score pour chaque terme de la requête de recherche, puis enregistrez le résultat dans une table de hachage ou quelque chose de similaire. Ceci est votre premier vecteur, appelé v_1. Ensuite, passez au premier document. Calculez également le score tf-idf pour chaque terme du document et enregistrez-le sous le nom v_2. Vous pouvez maintenant calculer un score pour ce document en utilisant la similitude en cosinus :

score = arccos(v_1 * v_2 / (|v_1| * |v_2|))

Le résultat est une valeur qui peut être utilisée pour classer le document. Continuez et faites ceci pour chaque document. Les trier dans l'ordre décroissant. Le premier document de la liste sera le plus pertinent.

Cela peut sembler un peu compliqué, mais si vous avez des notions de base en algèbre linéaire, vous pourrez probablement trouver une solution de travail en quelques heures. Néanmoins, utilisez si possible une solution existante telle que lucene.

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