【问题标题】:Query on MongoDB GridFS metadata (Java)查询 MongoDB GridFS 元数据 (Java)
【发布时间】:2012-05-04 03:03:39
【问题描述】:

我要做的是通过查询元数据的字段来获取 GridFS 文件的列表。例如,我得到一个 GridFS 文件文档,如下所示:

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

我想查询所有包含“target_field”=“abcdefg”的文件。我创建了如下查询:

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

列表总是空的。否则查询文件名或uploadDate 工作完美。难道不能通过嵌套属性获取GridFS文件吗?

【问题讨论】:

  • 会不会是你拼错了什么?这在我的机器上运行良好。我使用 mongod 2.0.4 和 v2.7.3 作为 Java 驱动程序。

标签: java mongodb gridfs


【解决方案1】:

不幸的是,我没有让它与嵌套的 BasicDBObjects 一起使用。

最后我使用了很好的点符号:

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

【讨论】:

  • 感谢您回答自己的问题。我有类似的困境,你的回答帮助我解决了它们。
【解决方案2】:

来自 MongoDB 文档 (http://docs.mongodb.org/manual/tutorial/query-documents/#exact-match-on-the-embedded-document):

嵌入文档的精确匹配

要在整个嵌入文档上指定相等匹配,请使用查询文档 { : } 其中要匹配的文档。嵌入文档上的相等匹配需要指定的完全匹配,包括字段顺序。

嵌入文档中字段的相等匹配

使用点符号来匹配嵌入文档中的特定字段。嵌入文档中特定字段的相等匹配将选择集合中的文档,其中嵌入文档包含具有指定值的指定字段。嵌入的文档可以包含其他字段。


我写了一个简单的代码来将“文档表示法”翻译成“dotted notation”。我希望它有用。

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

为了您的目的:

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

【讨论】:

  • 使用此代码时要小心。它将整个查询展平,包括像$in$nin 这样的运算符。我相信为了开发团队的理智,应该避免这种情况,并且从一开始就用点表示法编写查询。
【解决方案3】:

更简单:

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

【讨论】:

  • 也许您可以解释一下这段代码如何更好或更简单,正如您所说,而不是让读者尝试找出原因?
  • 问题不是通过其 md5 代码获取文件,而是通过元数据部分中的属性查找文件。此属性在元数据和 md5 的分层之下是实际问题。
猜你喜欢
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
  • 2016-12-24
  • 1970-01-01
  • 1970-01-01
  • 2014-05-25
  • 1970-01-01
相关资源
最近更新 更多