ReQL: hassle-free JSON processing
rethinkdb.com
rethinkdb.com
Being able to compose queries in a language-native way is really effective but also powerful in that you are essentially running programs on the database that it understands enough to optimize and distribute amongst its fellow servers. Not only that, you really can marry your code with the forms you send to the database, making it easy to compose queries that are built from conditionals from local variables.
Also because of the expressiveness, there are almost no places where I ever run two queries when selecting data. For instance in Mongo, I always used to do "get X. If X is this, then get Y, otherwise get Z." Now all that logic can be shipped off to the database (without having to build some huge SQL string) and when I get an answer back, it's the one I want.
Great query language, great database, great team.
It's easy to pretty-print and get a view of the entire query structure before it's shipped off the the protocol buffer serializer. That's lisp though, and the print methods for the protobuf objects are built into the protobuf library. It's really going to depend on your language, probably.
The nice thing about the query language is that the mapping between what you send the driver and what the driver sends to the server is pretty much 1:1, so what you see in front of you is the printed query (save for bugs in the driver).
Similar:
- Avi Bryant's Relational Object Expressions bring relational algebra into the programming language:
courseTitlesForProfessorNamed: aString
|courses|
courses := (professors * courses
select: [[:ea | (ea lastName = aString) & (ea id = ea professorID)].
^ (courses project: #title) copyFrom: 1 to: 10.
http://www.cincomsmalltalk.com/userblogs/avi/blogView?showCo...: and http://c2.com/cgi/wiki?RelationsAsFirstClassObjects- The query system for the Gemstone object database evaluates query blocks against proxies that capture the messages and translate the procedural queries into logical queries:
myEmployees select: { :emp | emp.age > emp.lengthOfService }
http://community.gemstone.com/download/attachments/6816350/G...However, the whole idea of overloading operators to pass in Python functions that somehow get converted... makes me feel uneasy, like it's too-clever-by-half -- having to keep track of which operators are actually supported, which client languages (Python, PHP, etc.) support it, if something's being messed up along the way...
Is there an alternative string syntax for such functions, written in a ReQL-specific language that can be used instead?
In practice, it turns out that most people pick ReQL up very easily and don't get confused or annoyed by these issues after getting acquainted with the language. That being said, we've toyed with the idea of having a string-based implementation, so people who are uneasy about these features could use the model they're already familiar with. (We didn't do this yet, but we likely will if there's enough demand for it)
Guido contributed to NDB.
Interestingly, the server protocol doesn't require the use of lambdas in the driver (and knows nothing about it). So in languages that don't support them, one could design a driver with a very different feel that work for that language, and it would still work well with RethinkDB. You could even write a completely string-based driver, and it would work well. (Though we didn't think through what a good C driver for Rethink would look like; we really wanted to focus on Ruby, Python, and JavaScript and offer a great experience in those languages).
Since dictionaries are first class objects in Python this is very easy to work with. Accepting extras from the command line is an example:
query={"last_name": "smith", "year": {"$lt": 2001}}
query.update(json.loads(argv))
They do use the chaining for the non-query values bit (sort order, limits etc).