 So I'm going to talk about Mongoid, about some of the latest developments that have been going on, what we're doing to keep pushing it forward. My name is Bertard Schaefer, it's a BJ Schaefer on Twitter, I'm on GitHub, and that's my blog at Zoinipa.com, and I work for Hash Rocket. So we're going to be talking about Mongoid, and in particular I want to talk about how we've come to embrace Rails 3, and how Mongoid has all along really embraced Mongoid itself. But first, I want to wish Mongoid a happy birthday. This is exactly one year ago today that Durin pushed the first commit for Mongoid, and it's been growing like crazy. We've had 88 contributors, 40 contributors in the last two months with 300 commits, that's the impact graph for on GitHub. If you look at another Mongo library, that's the impact graph. So there's a real community behind Mongoid, we've got good documentation, we've got an active IRC channel, we have a mailing list, and it's global now, we've got for all of the error messages and validation messages, we have all of these languages supported, it's really easy to fork and add your own, we're always looking to gather as many new languages and people as possible. So that's kind of the, just a quick intro I just wanted to say, so we're going to talk about Rails 3. We really love Rails 3 and we've been trying to embrace it as much as possible, get as much in there. First thing is the rail ties, you can start up a new Mongoid app, you Rails new, give it your app name, dash m, pass it at Mongoid.org, Rails.rb, that gives you a lot of different things, it gives you the generators, you can create a model just like you would with ActiveRecord, you can pass it the field names and types, that will spit out this. And then we've also taken on ActiveModel, because it's all sorts of things, validations, all the standard validations that you expect with Rails, serialization, JSON, XML, all that good stuff, mass assignment, adder protected, accessible, works just like it would with ActiveResource, but still agnostic. So we're running with Sinatra, all of our stuff that's rail specific is in the rail tie, it's only there if you need it. Sinatra Pedrino has built-in support for Mongoid and what's cool is that Mongoid lets you work with other ORMs, because eventually, or oftentimes you'll need to have some sort of SQL solution, you can use it with Datamapper, you can use it with ActiveRecord, it just works for cross-associations. All right, so that gets a little bit of the Rails 3 stuff out of the way. We've been spending a lot of time recently on that, but now I want to talk about MongoDB and like to say that an ORM or an ODM is what we call object document mapper, that it loves its database, I think seems like it doesn't need to be said, but it still does need to be said. We've embraced all of the core tenets of MongoDB and for us, if there's something that you can do with Mongo that you can't do with Mongoid, then that's a bug and you should file an issue and let us know, because we want to support everything that Mongo supports. The Mongoid is really built to support a lot of the core Mongo features, fast in place updates, rich document based querying, replication and high availability. These are pulled just straight from the Mongo website. Some of the core tenets, I think, of how MongoDB is built and how you can best use it, and so I want to focus on these things, what we've done recently to really support all of these things that Mongo does, is in place updates. So you've got a person and it embeds many addresses, so that's going to be stored on the actual person document. And then our address embeds many locations as well. So a person might have, I don't know, summer home somewhere or something, and locations might be city names. And so if you look at the person's attributes, you'll see you've got your person's attribute, its ID, has it addresses, there's an array of hashes, which also have IDs, and then that's going to have an array of hashes of locations. We could go through and we could grab the location, set it to Austin. Other Mongo libraries will push the full document graph when we go to do that update. So this is what it would turn into like in Mongo. We're going to call update, and we're going to have to pass it the entire document graph in order to do this update. So Mongo does it the Mongo way, which is that when you call update on something that's nested, it's only going to push exactly what is nested. So here what it's doing is it's finding, the first part is saying, okay, we're going to update the user, the ID one, and the, who has an address with an ID of two. And then we're going to push onto that, this new value for our location, which is significantly more optimized, much better way to do it, and it's the way that Mongo suggests you do it. And this applies to almost everything in Mongo. So all of the, it tracks your dirty changes and only pushes the new things. It uses the same syntax to do that. It'll, it finds the best way to push it out to the database, while pushing the least amount of data as possible across the wire. Rich query language, you know, this is one of the big features that Mongo has over other document databases, is that, say, like Couch, where you've got everything is MapReduce. Mongo doesn't take that point of view. They want to have a rich query language, but still built on top of a document database. And so Mongo supports all of this as well. You can have, you know, standard where clause, if you have an, an all, you can pass it multiple parameters like that. You can say it less than 24, greater than 18. You run in queries. You can also efficiently query nested documents. So here we're gonna find the person who has any address or location that maps to Austin. And then that carries over into the name scopes as well. So we get active, you know, this was the, kind of like the query that we ran before where we said, you know, age is greater than something. We'll wrap it up into a scope and call that over. Now we can say where the name matches a regular expression. It's active and is over 40. And this will turn into a very efficient Mongo query. And you can even do more filtering on top of that. Geospatial indexes, this is something that was added to Mongo in 1.4, which is just a few months ago. And it's another place where Mongo really tries to emphasize that you should be able to query whatever you want. And so here's how you do it with Mongo aid. We have our spot, I'm using terminology from Gawalla. We have a spot, we put something like a lat long field that's in array. It's gonna be, you know, two numbers. And we're gonna create a geo 2D index. Mongo doesn't have 3D geo indexing yet, but it's in the works. And if you're interested in that, then you should upvote the ticket. So we can create our spot, Old Town Ale House. This is my favorite bar in Chicago. Those are the coordinates for it. And so now what can we do with this? Oh, we can try to find other things that are nearby. So again, we could use the same rich query syntax that Mongo gives us to say, we want all the spots where the lat long is near that. And so that's with Mongo, it's gonna turn into almost exactly the same query and that will sort all the results by the distance that they are from the current location. So you would want to add some sort of a limit at the end of that. We also do something a little bit more complex. We can find, we can do a radius search. So here we're gonna try and find all of the places that are within 0.01. And I'm not exactly sure what the radius corresponds to. You have to tweak it to figure out. But so we're gonna find all the things that are nearby in this circular radius. You can also do box radiuses, radii, and except for ourselves. But that looks pretty ugly, I think at least. So we can again use the scopes that Mongo had exposed here to create a very nice API on top of the existing supported features. So we'll write the same query that we did before. We'll wrap it up in a scope and now we can find all the spots near the ale house with a certain limit. So replication and high availability. This is again, no SQL databases. This is what most of them are built for. And this is one of the core features of Mongo. But I think first I wanna talk about how it worked in 1.4. Before I talked about how it now works in 1.6. Which came out just a couple of weeks ago. 1.4, your replication option was master slave. You got one big master and some number of slaves. You started like this, you'd say, Mongo D master, here's where it is. Take the slave, point it at the master, some other slave, point that one at the master. And the way that it works then internally is you'll go, you'll write something to the master. At some point, it will be synced to the slaves. There's no guarantee of when it would be pushed. But it's required for durability. So Mongo right now does not have single server durability. So you have to have at least two servers running. And so we have to have at least one master and at least one slave. With Mongo, this is all we have to do. We just point it at master, we create, it's gonna write master. But we need the slaves, so why don't we use them? So MongoD comes with the ability to specify the list of slaves that you have. And then you can run queries, you can run read queries against your slaves. So here this in slave can be attached to almost anything that you do in MongoD. And it will, it has an internal counter and it will round robin between all of your slaves. But the problem with this is that it doesn't give you enough control. There's no guarantees for syncing, no automatic fail over. So in this case, if we create this user, it's gonna write to the master. Then we connect to the slave, we go to ask for the user and it's not there. And at some point, maybe it's two seconds, maybe it's not. Then we finally get it there, but no control over that. The other thing is master goes down. You can't see that, but I said kill, bit of master. In order to recover from this, we have to kill one of the slaves, bring that one back up as the master and then try to figure out what went wrong with the master. So the solution to that then is replica sets in 1.6. This is a significantly better way to do it. And so now what we do is we start up MongoD with a repl set. And there's no inherent master or slave here when you first started up. You'll then run a command to configure your replica set, and then you're off. And what's great is that it works the same way. So you can still point MongoD at your slaves, still have your reeds come from there, but it gives you all of the control. Guarantees for syncing, MongoD, you can say attach safely to almost anything. Here you can pass it an fsync option, which will make sure that it writes to disk before it returns. You pass it w, then it's for write, and that will ensure that it's written to two of your nodes before it returns. You also pass it a timeout to have it raise an error if it takes too long. And it can be done on anything. You can do it on the instance level, class level, destruction, updates, inserts, all that stuff. And then automatic failover. What's great is that all of this stuff is handled by the actual Ruby driver. We kill our Mongo process, try to create, it doesn't work. Two seconds later we try to create, and it works. And so what happened there is that when our server went down, the Mongo Ruby driver says, I got a connection failure. I'm gonna try and find one of the other nodes available in the system. And I'm gonna redirect rights to that. So after some number of seconds, Mongo will have the ability to promote one of the other service master. And then everything starts working again without having any intervention. And we've implemented a lot of other things as well. Recently, basically everything that was new in 1.6 is supported in Mongo and it was supported within like a week or two of the new release. And like I said, if you can do it with Mongo, then you'll be able to do it with Mongo and so what's next for us really depends a lot on what happens in Mongo, that's what really drives most of the features other than all the things that we like to do for day to day support. We're gonna have the release candidate up end of next week. This weekend we'll have beta 17 up, which will support RC2 of Rails. And we'll have a lot of fixes for associations. We've done a rewrite of the associations to make them significantly better and faster. And then it's whatever happens in Mongo. Virtual collections for embedded documents. This is something that's up on the JIRA. It would allow you to query for and insert directly into embedded documents without having to talk to the parent documents. Real date support, this has long been a frustration for us using Mongoid and there hasn't been a great solution yet, but it's supposed to be fixed in 1.7. Another feature that's up that people are talking about is capped arrays. So this would work just like Mongo has capped collections, which allow you to specify a particular size in a sort order. And you can just throw all the data that you want at it and never grows above the size that you want. People are talking about doing the same thing to have for embedded documents. And that's how Mongoid versioning works. You just include that. And as you make changes, it inserts a copy of the document on itself. And this would be a great use case, being able to do that. Yeah, I guess I want to do that kind of quickly. But this is where you can get the slides if you're interested. Mongoid site and Mongoid source. And hopefully you guys have a bunch of questions. Anyone? Yes? Does your Ruby 1.9 support? Fully supported. Yes, we run the entire test suite against 187, REE, 187, 191, 192. And we've run it against JRuby as well and that's all good. Yes? I guess about a year ago, when you had relational associations, has that changed? So the question is about using Mongo for relational sort of association. No, I mean, I think it's all about the different use cases that you envision, the way that you're modeling your documents. Certainly, embedding everything is a bad idea. And people from Mongo will tell you that, and that's what Dern will say too. But if you have too many relational associations, then you begin to, you have to question whether Mongo is really the right choice. Because you can't have, there's no consistency between, there's no safety between making changes to separate collections. There's no transactions between them. Each, you have atomic updates for embedded documents, not for the others. So if you find yourself using too many of them, then that's a good sign that you should probably be looking at using a relational database for at least some of those links. Any others? Yes? Yes, you can say, you can set in the config, there's a safety config option, I think. And you can just say safety equals whatever you want. So Fsync1 or W2, any of those sorts of things. And that will apply through your entire app. All right, well, I guess if that's it, then come ask me any questions if you want. And you should hop on, come contribute. We love having you people working on it. Thanks.