10

What I'm trying to do is fetching a list of GridFS files by querying an field of the metadata. For example I got a GridFS file document looking like:

{ "_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"}}

And I want to query all files containing "target_field" = "abcdefg". I created my query as follows:

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

The list is allways empty. Otherwise querying the filename or uploadDate works perfectly. Isn't it possible to get the GridFS files by nested attributes?

sebastian
  • 2,427
  • 4
  • 32
  • 37
  • Could it possibly be you misspelled something? This works fine on my machine. I am using mongod 2.0.4 and v2.7.3 for the Java driver. – Ren Apr 23 '12 at 16:33

3 Answers3

16

Unfortunately I didn't get it to work with nested BasicDBObjects.

Finally I was using the dot notation which works fine:

// This query fetches the files I need
BasicDBObject query = new BasicDBObject("metadata.target_field", "abcdefg"));
List<GridFSDBFile> files = gridFs.find(query);
sebastian
  • 2,427
  • 4
  • 32
  • 37
0

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

Exact Match on the Embedded Document

To specify an equality match on the whole embedded document, use the query document { : } where is the document to match. Equality matches on an embedded document require an exact match of the specified , including the field order.

Equality Match on Fields within an Embedded Document

Use the dot notation to match by specific fields in an embedded document. Equality matches for specific fields in an embedded document will select documents in the collection where the embedded document contains the specified fields with the specified values. The embedded document can contain additional fields.


I wrote a simple code to translate the "document notation" in "dotted notation" . I hope it's useful.

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;
}

For your purpose:

List<GridFSDBFile> files = gridFs.find(buildMetadataSearchQuery(new BasicDBObject("target_field", "abcdefg")));
Francesca Merighi
  • 317
  • 1
  • 3
  • 10
  • Be careful when using this code. It flattens the whole query, including operators like `$in` or `$nin`. I believe for sanity of the development team, this should be avoided and queries written in dot notation from the start. – madmuffin Jul 05 '17 at 09:08
0

Simpler:

GridFSDBFile gridFile = fsDocs.findOne(new BasicDBObject("md5","1b21bc40a456befc7d2ee10b0e25fabf"));
William Price
  • 4,033
  • 1
  • 35
  • 54
  • 2
    Perhaps you could explain how this code is better or simpler, as you say, rather than making readers try to spot why? – William Price Dec 31 '14 at 01:53
  • The issue was not to fetch a file by its md5 code but find the file by an property that is within the metadata part. This property is hierarchically below metatdata and md5 which has been the actual problem. – sebastian Jan 07 '15 at 09:19