我正在创建一个拥有大量音频存储(TB 级)的网站,我希望使用 GridFS 进行分片,并能够轻松地跨多台计算机扩展数据库。
我的问题是,将文件放在单独的 mongo 数据库中会更好吗?mongodb 中会有大量文档,我只是不确定当您开始使用 GridFS 部分进行分片时会发生什么。
谢谢!
我在Openshift中使用Python + MongoDB + PyMongo
import os
import gridfs
from django.http import HttpResponse
from pymongo.connection import Connection
from django.shortcuts import get_object_or_404, render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.template import Context, RequestContext,loader
connection = Connection('mongodb://sbose78:XXXXXX@staff.mongohq.com:10068/BOSE')
db=connection['BOSE']
fs=gridfs.GridFS(db)
Run Code Online (Sandbox Code Playgroud)
当我通过_id查询文件时,这就是我得到的.
>>> fs.exists({"_id":'504a36d93324f20944247af2'})
False
Run Code Online (Sandbox Code Playgroud)
当我用相应的文件名查询时:
>>> fs.exists({"filename":'foo.txt'})
True
Run Code Online (Sandbox Code Playgroud)
什么可能出错?
谢谢.
我有一个引用 GridFS 文件的集合,通常每条记录 1-2 个文件。这些集合相当大 - 父集合中大约有 705k 条记录,以及 790k GridFS 文件。随着时间的推移,出现了许多孤立的 GridFS 文件 - 父记录已被删除,但引用的文件并未被删除。我现在正尝试从 GridFS 集合中清除孤立文件。
这里建议的方法的问题在于,将 700k 记录组合成一个大的 ids 列表会导致内存中大约 4mb 的 Python 列表 - 将其传递到 Mongo 中 fs.files 集合上的 $nin 查询实际上需要永远。执行相反的操作(获取 fs.files 中所有 id 的列表并查询父集合以查看它们是否存在)也需要很长时间。
有人遇到过这个问题并开发出更快的解决方案吗?
大家好我使用collectionfs + gridfs + cfs文件系统,在collectionsfs文档中,我发现如何在客户端插入文件,如下所示:
Template.myForm.events({
'change .myFileInput': function(event, template) {
FS.Utility.eachFile(event, function(file) {
Images.insert(file, function (err, fileObj) {
//Inserted new doc with ID fileObj._id, and kicked off the data upload using HTTP
});
});
}
});
Run Code Online (Sandbox Code Playgroud)
在这种情况下将在客户端插入文件,但在我的情况下我删除不安全,所以不能在客户端插入,我尝试在服务器端进行.所以这是我的代码:
Template.myForm.events({
'change . myFileInput': function (event, template) {
FS.Utility.eachFile(event, function (file) {
var reader = new FileReader();
reader.onload = function (fileLoadEvent) {
Meteor.call('ImageUpload', file, reader.result, function (err, res) {
if (err) {
console.log(err);
} else {
alert(res);
}
});
};
reader.readAsBinaryString(file);
}); …Run Code Online (Sandbox Code Playgroud) 我试图使用gridfs删除我的mongodb数据库中的文件.我想删除所有带有metadata.relation = id的文件.这是我在NodeJS中的方法:
function deleteFiles(){
gfs.remove({'metadata.relation': req.body._id }, function(err){
if (err) return false;
return true;
})
}
Run Code Online (Sandbox Code Playgroud)
错误是:
C:\ Users\Gaute\Documents\GitHub\WikiHelpSystem \node_modules\mongoose \node_module s\mongodb\lib\mongodb\gridfs\gridstore.js:1138
if(names.constructor == Array){Run Code Online (Sandbox Code Playgroud)^TypeError:无法在Function.GridStore.unlink中读取未定义的属性'constructor'(C:\ Users\Gaute\Documents\GitHub\WikiHelpSystem \node_modules\mongoose \node_modules\mongodb\lib\mongodb\gridfs\gridstore.js:1138: 11)
我有一个关于缓冲区的问题。这是我的代码:
var Grid = require('gridfs-stream');
var mongodb = require('mongodb');
var gfs = Grid(db, mongodb);
var deferred = Q.defer();
var image_buf = new Buffer('buffer');
var readableStream = gfs.createReadStream(name);
readableStream.on('data',function(chunk){
console.log(chunk);
image_buf = Buffer.concat([image_buf, chunk]);
console.log(image_buf)//differ from the chunk above
});
readableStream.on('end',function(){
db.close();
deferred.resolve(image_buf);
})
return deferred.promise;
Run Code Online (Sandbox Code Playgroud)
我正在做的是从 MongoDB 读取图像并将其放入 gridfs-stream 中。我真的想检索流中的所有块并将它们传递给另一个变量,以便我可以重用这些块在另一个 API 中绘制图像。因此我使用 image_buf 和 Buffer 来执行任务。但是,我得到了一个完全不同的缓冲区字符串。正如你在上面的代码中看到的,我安慰了我得到的 chunk 和 image_buf,但它们是完全不同的。谁能告诉我这样做的原因以及如何正确收集所有块?多谢!!!
更新:好的,所以我现在想通了:我将在下面附加我的代码,供任何遇到与我相同问题的人使用:
readableStream.on('data',function(chunk){
console.log("writing!!!");
if (!image_buf)
image_buf = chunk;
else image_buf = Buffer.concat([image_buf, chunk]);
});
Run Code Online (Sandbox Code Playgroud) 我有一个函数将文件保存到gridfs.在某个重构之后它以某种方式停止了零星的工作,我花了两个多小时茫然地盯着它.我发誓它和它一样大致相同.我似乎记得它在我加入之前没有工作,然后它开始工作,但它可能是失眠.基本上问题是db.fs.files集合没有任何记录,但是块被添加到db.fs.chunks.
data是通过fs.readFile()从磁盘加载的缓冲区
31 var gs = new mongodb.GridStore(this.db, filename, "w", {
32 "chunk_size": 1024*4,
33 metadata: {
34 hashpath:gridfs_name,
35 hash:hash,
36 name: name
39 }
40 });
41 gs.open(function(err,store) {
42 gs.write(data,function(err,chunk) {
43 //cb(err,hash,chunk);
44 //self.close();
45 });
46 });
Run Code Online (Sandbox Code Playgroud) 我已经设置了一个包含4台服务器的副本集.
出于测试目的,我编写了一个脚本,使用GridFS将我的数据库填充到大约1.5亿行照片.我的照片约为15KB.(对于小文件使用gridfs应该不是问题吗?!)
几个小时后,有大约5000万行,但我在日志中有这样的消息:
replSet error RS102 too stale to catch up, at least from 192.168.0.1:27017
Run Code Online (Sandbox Code Playgroud)
这是replSet状态:
rs.status();
{
"set" : "rsdb",
"date" : ISODate("2012-07-18T09:00:48Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.0.1:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"optime" : {
"t" : 1342601552000,
"i" : 245
},
"optimeDate" : ISODate("2012-07-18T08:52:32Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.0.2:27018",
"health" : 1,
"state" : 3,
"stateStr" : …Run Code Online (Sandbox Code Playgroud) C:\Programs\MongoDB\bin>mongofiles.exe list
connected to: 127.0.0.1
test123.txt 6
test123.txt 22
test123.txt 44
test456.txt 53
test456.txt 53
test456.txt 53
test456.txt 53
test456.txt 53
test456.txt 15
C:\Programs\MongoDB\bin>
Run Code Online (Sandbox Code Playgroud)
当我这样做时,mongofiles get test456.txt我总是得到
我在GridFS中使用该名称放的最后一个文件.
如果它们都有重复的名称,我如何获得其他/以前的?
根据我需要指定的文档:
"文件名,它是:
本地文件系统上的文件名或GridFS对象."
http://docs.mongodb.org/manual/reference/program/mongofiles/
但对于我来说,"GridFS对象"在这种情况下意味着什么并不是很清楚.