-
Notifications
You must be signed in to change notification settings - Fork 5
3. GridFS File Storage
CBMongoDB includes an interface and Active Entity implementation for using MongoDB's GridFS for relational, distributed file storage. Let's say, for example, that we want to associate profile images to our people collection.
Let's create a relational entity that will be responsible for storing and retrieving profile pictures. Our component should extend cbmongodb.models.FileEntity
. An additional component attribute may be specified with the name of the bucket used to store the file data. By default, Mongo uses a bucket named fs
.
component name="ProfileImages" extends="cbmongodb.models.FileEntity" collection="profileImages" bucket="images" accessors=true{
//normalize our person information, in case we need it for captions and alt information.
//Note that we are using auto-normalization of the first_name and last_name keys on our person entity
property name="person" schema=true normalize="Person" on="person.id" keys="first_name,last_name";
property name="person.id" schema=true required=true;
}
Because the querying syntax for GridFS files differs from our standard query syntax, entities use a standard MongoDB collection which connects to the GridFS file object. Every FileEntity schema contains a property fileId
which allows for a one-to-one relationship to the GridFS file.
We can load a file in directly from a local path, for example a file uploaded to a temporary directory:
var Person = getModel("Person").load("54e523599b67bde3c7b2f03d");
var ProfilePhoto = getModel("ProfileImages")
//Set and normalize our person model
ProfilePhoto.set('person.id',Person.get_id())
//Load our photo in to grid FS and pass the optional argument to delete the file after it has been loaded
ProfilePhoto.loadFile(filePath=expandPath('/includes/tmp/MyProfilePhoto.jpg'),deleteFile=true);
ProfilePhoto.create();
Once we've created our profile photo, we can retrieve using our person relationship:
var ProfilePhoto = getModel("ProfileImages").where('person.id',Person.get_id()).find();
A simple example would be to retrieve the file and write it back out to the file system. The writeTo
returns the written file path method can accept either a full path or a directory. If only a directory is specified, the file will be written with the fileId as the name of the file.
var imageFile = ProfilePhoto.writeTo(expandPath('/assets/images/profiles/MyProfileImage.jpg'));
For images, we can also provide a struct of arguments to resize or crop the image before writing it out to the file system.
-
width
: The maximum width of the image. If crop x and y coordinates are specified, this will be the actual width. Otherwise, if only height and width are provided, the image will be scaled to the maximum height/width constraints. -
height
: Same aswidth
, but for height -
x
: The horizontal center of the cropped image from the top left corner of the original image -
y
: The vertical center of the cropped image bounding box
Write a scaled image which will be no larger than 100x100 pixels wide:
var imageFile = ProfilePhoto.writeTo(
Path=expandPath('/assets/images/profiles/MyProfileImage.jpg'),
imageArgs={"height":100,"width":100}
);