2012-04-23 4 views
9

Ce que j'essaie de faire est d'extraire une liste de fichiers GridFS en interrogeant un champ des métadonnées. Par exemple, je suis un document de fichier GridFS ressemblant à:Requête sur les métadonnées MongoDB GridFS (Java)

{ "_id" : { "$oid" : "4f95475f5ef4fb269dbac954"} , "chunkSize" : 262144 , "length" : 3077 , "md5" : "f24ea7ac05c5032f08808c6faabf413b" , "filename" : "file_xyz.txt" , "contentType" : null , "uploadDate" : { "$date" : "2012-04-23T12:13:19.606Z"} , "aliases" : null , "metadata" : { "target_field" : "abcdefg"}} 

Et je veux interroger tous les fichiers contenant « target_field » = « abcdefg ». J'ai créé ma requête comme suit:

BasicDBObject query = new BasicDBObject("metadata", new BasicDBObject("target_field", "abcdefg")); 
// gridFS Object Initialization skipped 
List<GridFSDBFile> files = gridFs.find(query); 

La liste est toujours vide. Sinon, interroger le nom de fichier ou uploadDate fonctionne parfaitement. N'est-il pas possible d'obtenir les fichiers GridFS par attributs imbriqués?

+0

pourrait-il vous avez mal orthographié peut-être quelque chose? Cela fonctionne très bien sur ma machine. J'utilise mongod 2.0.4 et v2.7.3 pour le pilote Java. – Ren

Répondre

15

Malheureusement, je ne l'ai pas fait fonctionner avec BasicDBObjects imbriqués.

Enfin, j'utilisais la notation de points qui fonctionne très bien:

// This query fetches the files I need 
BasicDBObject query = new BasicDBObject("metadata.target_field", "abcdefg")); 
List<GridFSDBFile> files = gridFs.find(query); 
+1

Merci d'avoir répondu à votre question. J'ai eu une situation similaire et votre réponse m'a aidé à les résoudre. –

0

De la documentation MongoDB (http://docs.mongodb.org/manual/tutorial/query-documents/#exact-match-on-the-embedded-document):

Exact Match sur le document incorporé

Pour spécifier une correspondance d'égalité sur la utilisez le document de requête {:} où le document doit correspondre. Les correspondances d'égalité sur un document incorporé requièrent une correspondance exacte de l'objet spécifié, y compris l'ordre des champs.

égalité match sur les champs dans un document intégré

Utilisez la notation des points en fonction des champs spécifiques dans un document incorporé. Les correspondances d'égalité pour des zones spécifiques dans un document incorporé sélectionnent les documents de la collection dans lesquels le document incorporé contient les champs spécifiés avec les valeurs spécifiées. Le document incorporé peut contenir des champs supplémentaires.


j'ai écrit un simple code à traduire la "notation de documents" dans "la notation en pointillé". J'espère que c'est utile.

protected static void toDottedJson(Object o, String key, DBObject query) { 
    if (o instanceof Map) 
     for (Entry<?, ?> c : ((Map<?, ?>) o).entrySet()) 
      toDottedJson(c.getValue(), key + "." + c.getKey().toString(), 
        query); 
    else 
     query.put(key, o.toString()); 
} 

public static DBObject buildMetadataSearchQuery(DBObject searchQuery) { 
    BasicDBObject metadatSearchQuery = new BasicDBObject(); 
    for (Entry<?, ?> c : ((Map<?, ?>) searchQuery).entrySet()) 
     toDottedJson(c.getValue(), "metadata." 
       + c.getKey().toString(), 
       metadatSearchQuery); 
    return metadatSearchQuery; 
} 

Pour votre but:

List<GridFSDBFile> files = gridFs.find(buildMetadataSearchQuery(new BasicDBObject("target_field", "abcdefg"))); 
+0

Soyez prudent lorsque vous utilisez ce code. Il aplatit toute la requête, y compris les opérateurs comme '$ in 'ou' $ nin'. Je crois que pour la santé mentale de l'équipe de développement, cela devrait être évité et les requêtes écrites en notation point dès le début. – madmuffin

0

Simpler:

GridFSDBFile gridFile = fsDocs.findOne(new BasicDBObject("md5","1b21bc40a456befc7d2ee10b0e25fabf")); 
+2

Peut-être pourriez-vous expliquer comment ce code est meilleur ou plus simple, comme vous le dites, plutôt que de faire en sorte que les lecteurs essaient de comprendre pourquoi? –

+0

Le problème n'était pas d'extraire un fichier avec son code md5, mais de trouver le fichier par une propriété située dans la partie des métadonnées. Cette propriété est hiérarchiquement inférieure à metatdata et md5 qui a été le problème réel. – sebastian

Questions connexes