java - 更新元数据后发现不适用于 GridFS

标签 java gridfs mongo-collection

我在应用程序中添加了一个步骤,通过 GridFS 保存文件,并添加了一个名为“已处理”的元数据字段,作为计划任务的标志,该任务检索新文件并将其发送以进行处理。由于 GridFS 的 Java 驱动程序没有允许更新元数据的方法,因此我使用 MongoCollection 作为“fs.files”集合来将“metadata.processing”更新为 true。

我使用GridFSBucket.find(eq("metadata.processed", false)来获取要处理的新文件,然后在处理完成后将metadata.processed更新为true。如果我在应用程序时添加新文件,则此方法有效但是,如果我有一个现有文件,并将“metadata.processed”设置为 false 并启动应用程序,则上面的 find 调用不会返回任何结果。同样,如果我有一个已处理的文件,并且我将“metadata.processed”设置为 false,则上述 find 调用不会返回任何结果。 processed” 字段返回 false,上面的 find 调用也停止工作。

private static final String FILTER_STR = "'{'\"filename\" : \"{0}\"'}'";

private static final String UPDATE_STR =
        "'{'\"$set\": '{'\"metadata.processed\": \"{0}\"'}}'";

@Autowired
private GridFSBucketFactory gridFSBucketFactory;

@Autowired
private MongoCollectionFactory mongoCollectionFactory;

public void storeFile(String filename, DateTime publishTime,
        InputStream inputStream) {

    if (fileExists(filename)) {
        LOGGER.info("File named {} already exists.", filename);
    } else {
        uploadToGridFS(filename, publishTime, inputStream);
        LOGGER.info("Stored file named {}.", filename);
    }
}

public GridFSDownloadStream getFile(BsonValue id) {
    return gridFSBucketFactory.getGridFSBucket().openDownloadStream(id);
}

public GridFSDownloadStream getFile(String filename) {
    final GridFSFile file = getGridFSFile(filename);
    return file == null ? null : getFile(file.getId());
}

public GridFSFindIterable getUnprocessedFiles() {
    return gridFSBucketFactory.getGridFSBucket()
            .find(eq("metadata.processed", false));
}

public void setProcessed(String filename, boolean isProcessed) {
    final BasicDBObject filter =
            BasicDBObject.parse(format(FILTER_STR, filename));
    final BasicDBObject update =
            BasicDBObject.parse(format(UPDATE_STR, isProcessed));
    if (updateOne(filter, update)) {
        LOGGER.info("Set metadata for {} to {}", filename, isProcessed);
    }
}

private void uploadToGridFS(String filename, DateTime publishTime,
        InputStream inputStream) {
    gridFSBucketFactory.getGridFSBucket().uploadFromStream(filename,
            inputStream, createMetadata(publishTime));
}

private GridFSUploadOptions createMetadata(DateTime publishTime) {
    final Document metadata = new Document();
    metadata.put("processed", false);
    // metadata.put("publishTime", publishTime.toString());
    return new GridFSUploadOptions().metadata(metadata);
}

private boolean fileExists(String filename) {
    return getGridFSFile(filename) != null;
}

private GridFSFile getGridFSFile(String filename) {
    return gridFSBucketFactory.getGridFSBucket()
            .find(eq("filename", filename)).first();
}

private boolean updateOne(BasicDBObject filter, BasicDBObject update) {

    try {
        mongoCollectionFactory.getFsFilesCollection().updateOne(filter,
                update, new UpdateOptions().upsert(true));
    } catch (final MongoException e) {
        LOGGER.error(
                "The following failed to update, filter:{0} update:{1}",
                filter, update, e);
        return false;
    }
    return true;
}

知道我可以做什么来确保:

GridFSBucket.find(eq("metadata.processed", false) 

返回现有文件和/或已更改元数据的文件的正确结果?

最佳答案

该问题是由于将metadata.processed 值设置为字符串而不是 boolean 值造成的。

最初创建元数据时,我使用 boolean 值设置其值:

private GridFSUploadOptions createMetadata(DateTime publishTime) {
    final Document metadata = new Document();
    metadata.put("processed", false);
    // metadata.put("publishTime", publishTime.toString());
    return new GridFSUploadOptions().metadata(metadata);
}

然后我检查 boolean 值:

public GridFSFindIterable getUnprocessedFiles() {
    return gridFSBucketFactory.getGridFSBucket()
        .find(eq("metadata.processed", false));
}

但是,当使用“fs.files”MongoCollection 更新元数据时,我错误地在此处的 boolean 值周围添加了引号:

private static final String UPDATE_STR =
    "'{'\"$set\": '{'\"metadata.processed\": \"{0}\"'}}'";

这导致元数据值被保存为字符串而不是 boolean 值。

关于java - 更新元数据后发现不适用于 GridFS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57894594/

相关文章:

mongodb - ReplicaSet 上的 RS102 MongoDB

java - MongoCollection updateMany、bulkWrite 还是其他?

java - 蒙戈集合 : How to get value of nested key

java - 预期的空指针导致意外的 InvokingTargetException

java - 尝试修改标识列 ' ID'

java - 如何使用GridFSInputFile和GridFS而不在MongoDB中添加文件并使用Java?

node.js - mongo-connect(session) 的 mongo-connect 错误

java.lang.NoSuchMethodException : AffirmativeBased. <init>()

java - 在android studio的所有activity中保留账户信息

node.js - 如何使用GridFS保存已保存文件的ID?