IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQLite Discussion :

Reconnaissance par tags dans une table mal formée


Sujet :

SQLite

  1. #1
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 162
    Points
    17 162
    Par défaut Reconnaissance par tags dans une table mal formée
    Bonjour tout le monde.

    Un peu de contexte: je reçois une base brute avec quelques données mal normalisées, et je veux les améliorer.
    Comme je ne reçois pas de patch de la base, mais des bases de remplacement, je veux créer un fichier de requetes sql à jouer à chaque fois.

    Concretement, mon sujet est de trouver les Objets qui a tout les Tags que demande une Action
    Par exemple, l'Objet (A, B, C) est une cible valide pour une Action qui requiert A et B, mais pas pour une demandant D. (J'ai aussi des requetes négatives, genre "pas B", mais ca n'est pas la question)

    Mon objectif réel est d'obtenir une vue action_targets(action_id, object_id).

    J'avais déjà réussi à traiter ca dans le temps, mais ma source de données à changée en pire.
    Avant, j'avais object_tags(object_id, tag), et action_tags(action_id, tag) avec une ligne par tag, et je m'en sortais avec une série de jointures.

    Maintenant, action_tags n'existe plus, et je n'ai plus qu'une unique chaine de texte (html!) dans action.
    J'ai réussi à extraire les parties marquées comme des tags dans le texte, mais il y a un hic. Les frontières des tags ne sont pas les bonnes: certains tags ont des espaces.
    Par exemple, j'ai maintenant "[a] [b] [c] [d]", mais l'intention était "[a b] [c] [d]".

    J'ai la liste des intentions possibles, mais il y a des recouvrements: en l'occurence, il y a "[a]", "[b]", "[a b]" et "[a b with f]".
    Si j'ai bien "[u v]" mais ni "[u]" ni "[v]", je sais d'avance pouvoir recoller u et v.

    Je n'arrive pas à trouver comment recréer action_tags. Avez vous des idées?
    Je suis peut-être en train de XY le mauvais problème. Peut-être devrais-je chercher à composer des phrases avec les tags des objets, et de les recoller avec les actions?

    Voici là où j'en suis arrivée: (en bonus, il y a une différence de majuscules (que like résout) et la gestion des crochets).
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    with recursive
    known_tags(tag) as (
    	-- represents a select distinct tag from object_tags order by length(tag)
    	values
    		('a b theta'),
    		('a b'),
    		('c d'),
    		('a'),
    		('b'),
    		('e')
    ),
    input(data) as ( 
    	values ('[a] [b] [c] [d] [e]')
    ),
    sqe(tags, tail) as (
    	select null, data from input
     
    	union all
    	select
    		iif(tags is null, keyword, tags ||','|| keyword),
    		substr(tail, length(bracketed) + 2)
    	from sqe
    	join (
    		select
    			tag,
    			'[' || replace(tag, ' ', '] [') || ']' as bracketed
    		from known_tags
    		order by length(tag) desc
    	) as mappings
    	on sqe.tail like bracketed || '%'
    )
    select tags from sqe where tail = '';
    pour le débug, on peut remplacer le dernier select par select * from sqe;.

    Je ne dois pas être loin, j'ai la bonne réponse (a b,c d,e) et un faux positif (a,b,c d,e), je ne vois pas comment rejeter 'a' sur la base de l'existence de 'a b' dans known_tags.

    Merci à vous!
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 195
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 195
    Points : 17 162
    Points
    17 162
    Par défaut
    Et bien j'ai trouvé une solution.
    Ma bonne réponse, c'est celle où j'ai regroupé utilisé les tags les plus long. Donc, où j'ai le moins de tags.
    En ajoutant un nombre de récursion, il suffit d'utiliser min(récursions) et un group by action_id.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    with recursive
    known_tags(tag) as (
    	-- represents a select distinct tag from object_tags order by length(tag)
    	values
    		('a b theta'),
    		('a b'),
    		('c d'),
    		('a'),
    		('b'),
    		('e')
    ),
    input(action_id, data) as ( 
    	values (1, '[a] [b] [c] [d] [e]')
    ),
    sqe(action_id, tags, size, tail) as (
    	select action_id, null, 0, data from input
     
    	union all
    	select
    		action_id,
    		iif(tags is null, keyword, tags ||','|| keyword),
    		size + 1,
    		iif(length(bracketed) = length(tail), null, substr(tail, length(bracketed) + 2))
    	from sqe
    	join (
    		select
    			tag,
    			'[' || replace(tag, ' ', '] [') || ']' as bracketed
    		from known_tags
    		order by length(tag) desc
    	) as mappings
    	on sqe.tail like bracketed || '%'
    )
    select action_id, tags, min(size) as size
    from sqe
    where tail is null
    group by action_id
    ;
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Champ independant: valeur par defaut dans une Table
    Par bakaccess dans le forum Access
    Réponses: 2
    Dernier message: 27/02/2008, 15h35
  2. [Conception] Enregistrer des tags dans une table ?
    Par Spylberg dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 20/07/2007, 12h54
  3. Enregistrement par batch dans une table
    Par mboubidi dans le forum Administration
    Réponses: 2
    Dernier message: 14/06/2007, 16h07
  4. [MySQL] Affichage de valeurs par selection dans une table
    Par Flushovsky dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 16/12/2005, 17h04
  5. Valeur par défaut dans une table objet
    Par Ricky81 dans le forum Oracle
    Réponses: 12
    Dernier message: 18/03/2004, 11h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo