Après beaucoup de débogage, j'ai trouvé.
La raison de ce comportement est une très euh malheureuse euh "décision de conception" prise par Adobe lors de la mise en œuvre de l'interface entre ColdFusion et Solr.
Vous avez donc une collection Solr de fichiers indexés et vous voulez purger sélectivement ceux qui n'existent plus sur le disque. Je suis presque sûr que c'est exactement la situation dans laquelle vous vous êtes trouvé.
Supposons :
- il y a un fichier appelé
/path/to/file
sur votre système et
- il est indexé dans la collection Solr
foo
.
Lorsque vous émettez un <cfindex collection="foo" action="delete" key="/path/to/file">
ColdFusion envoie la requête HTTP suivante à Solr :
POST /solr/foo/update?wt=xml&version=2.2 (application/xml; charset=UTF-8)
<delete><id>1247603285</id></delete>
Il s'agit d'une demande parfaitement raisonnable que Solr se fera un plaisir de satisfaire. La seule chose étrange est le nombre dans le champ <id>
. Dans tous les cas, le fichier aura disparu de l'index après cette opération.
Réindexez le fichier et supprimez-le du disque. Maintenant :
- il n'y a plus de fichier appelé
/path/to/file
sur votre système, mais
- c'est toujours indexé dans la collection Solr
foo
.
Faisons de même <cfindex action="delete">
opération de nouveau.
POST /solr/foo/update?wt=xml&version=2.2 (application/xml; charset=UTF-8)
<delete><id>/path/to/file</id></delete>
Huh ? Il ne devrait pas y avoir un numéro dans l'identification ?
Il s'avère que quelqu'un chez Adobe a pensé que ce serait une bonne idée d'utiliser des numéros pour les identifiants uniques des fichiers indexés, pour, euhhh, économiser de l'espace Je suppose.
Cependant pour une raison inexplicable, cela ne se produit que lorsque le fichier en question existe encore. S'il n'existe plus, ColdFusion le remarquera et passera le chemin à la place.
En inspectant le nombre, on constate qu'il correspondrait à une valeur entière signée de 32 bits. (J'ai vérifié, il y a beaucoup de valeurs négatives dans la base de données de l uid
de la collection).
Il semble donc qu'ils utilisent une sorte d'algorithme de hachage qui renvoie 32 bits et les mettent dans un int. Le CRC32 me vient à l'esprit, mais ce n'est pas ça. Aussi, java.util.zip.CRC32
renvoie un long
Il n'y aurait donc pas de valeurs négatives en premier lieu.
L'autre hachage 32 bits facilement disponible en Java est ... java.lang.Object.hashCode()
.
Bingo.
"/path/to/file".hashCode() // -> 1247603285
La solution est donc de ne jamais supprimer un fichier par son chemin d'accès, mais toujours comme ceci :
<cfindex collection="foo" action="delete" key="#path.hashCode()#">
Pour les fichiers qui n'existent plus, cela fait la bonne chose.
Plus important encore : Pour les fichiers qui existent toujours, cela fait également ce qu'il faut - ColdFusion aurait envoyé le code de hachage de toute façon.
Jusqu'à ce qu'Adobe corrige ce problème, il s'agit d'une solution de contournement sûre et facile.
Notez que le chemin du fichier est sensible à la casse et doit correspondre exactement à celui stocké dans l'index.
Un rapide
<cfsearch collection="foo" name="foo">
sans aucune criteria
retournera toutes les entrées de l'index, donc récupérer le chemin exact des entrées orphelines n'est pas un gros problème.
Eric Lippert explique les codes de hachage d'objets et pourquoi c'est une mauvaise idée de les utiliser pour quoi que ce soit de "pratique" dans une application. Il s'agit d'un article sur .NET, mais il s'applique tout aussi bien à Java.
Cela se résume à : Adobe devrait stocker les données chemin dans la collection Solr et laisser à Solr l'optimisation des performances qu'ils semblent avoir tenté.
J'ai déposé Bug 3589991 contre la base de données des bugs de ColdFusion d'Adobe.