Hacker News new | past | comments | ask | show | jobs | submit login
SpahQL - A query language for Javascript objects (angryamoeba.co.uk)
83 points by raystar on May 21, 2012 | hide | past | favorite | 34 comments



Interresting.

SQlike is another effort in the same direction. It provides a wide range of SQL features including joins. JavaScript tables are used as query language.

See http://www.thomasfrank.se/sqlike.html for an overview and http://www.thomasfrank.se/SQLike/ for examples.

    dataArray = [
    {firstName: "Paul", lastName: "Stele", age:35, salary:35000},
    ...
    ]

    dataArray2 = [
    {firstName: "Paul", lastName: "Stele", favColor:"green"},
    ...
    ]

    SQLike.q(
       {
           Select: ['*'],
           From: dataArray,
           Where: function(){return this.salary>50000},
           OrderBy: ['salary','|desc|']
       }
    )


    SQLike.q(
       {
           Select: ['*'],
           From: {t1:dataArray},
           NaturalJoin: {t2:dataArray2},
           Where:function(){return this.t1.firstName!='Vicki'}
       }
    )


This looks pretty handy for large datasets, to be sure.

SpahQL is definitely much lighter than that - the API is intended to be more jquery-like with a specific selector language, each selection returning a resultset object which then provides methods for subselections and modifications.


have you considered adopting the jsonpath syntax?

it would be more javascripty and would be another implementation (or a superset) of jsonpath

http://goessner.net/articles/JsonPath/ http://code.google.com/p/jsonpath/ https://github.com/joshbuddy/jsonpath https://github.com/marianoguerra/jsonpath-scala


Author here. I wanted to try something a little lighter than jsonpath and with a specific mode of (node collection|descent) that allowed set arithmetic to be the primary means of comparisons and assertions. This allowed me to obviate the need for scoped AND/OR structures and instead provide a broad range of assertion options using superset, subset, disjoint and joint set operations.

It's most certainly not perfect, but I had fun experimenting with it.


it's a nice project, and if it adds something extra then go for it :)

but sometimes I think jsonpath should be more visible and it's not, that's why I was trying to avoid fragmentation for the same solution. But as you said, it tries a different approach so it makes sense to use a different syntax.


linq.js has been doing this for years now. Its a mature library, flexible and light. I use it for every web project, wouldn't know what to do with out it. http://linqjs.codeplex.com/ Examples: http://neue.cc/reference.htm

  Features
  --------------------------------------  
  implement all .NET 4.0 methods and many extra methods
  (inspiration from Rx, Achiral, Haskell, Ruby, etc...)
  complete lazy evaluation
  full IntelliSense support for VisualStudio
  two versions - linq.js and jquery.linq.js (jQuery plugin)
  support Windows Script Host
  binding for Reactive Extensions for JavaScript(RxJS) and   
  IntelliSense Generator -> see documentation
  NuGet install support(linq.js, linq.js-jQuery, linq.js-Bindings)

  90 Methods
  ----------------------------------------
  Aggregate, All, Alternate, Any, Average, BufferWithCount,   
  CascadeBreadthFirst, CascadeDepthFirst, Catch, Choice,  
  Concat,Contains, Count, Cycle, DefaultIfEmpty, Distinct, Do,   
  ElementAt, ElementAtOrDefault, Empty, Except, Finally, First,  
  FirstOrDefault, Flatten, ForEach, Force, From, Generate,  
  GetEnumerator, GroupBy, GroupJoin, IndexOf, Insert, Intersect, 
  Join, Last, LastIndexOf,
  LastOrDefault, Let, Matches, Max, MaxBy, MemoizeAll, Min,  
  MinBy, OfType, OrderBy, OrderByDescending, Pairwise,  
  PartitionBy, Range, RangeDown, RangeTo, Repeat,  
  RepeatWithFinalize, Return, Reverse, Scan, Select, SelectMany,  
  SequenceEqual, Share, Shuffle,
  Single, SingleOrDefault, Skip, SkipWhile, Sum, Take,  
  TakeExceptLast, TakeFromLast, TakeWhile, ThenBy,  
  ThenByDescending, ToArray,
  ToDictionary, ToInfinity,ToJSON, ToLookup, ToNegativeInfinity,  
  ToObject, ToString, Trace, Unfold, Union, Where, Write,  
  WriteLine, Zip


Good utility, but I had a few specific itches to scratch with SpahQL:

* Declarative syntax for selections, such that selection queries may be handed between implementations in other languages

* Imperative syntax for updates, such that updates may be idiomatic to the language in which the spahql library has been ported (linq meets this criteria)

In essence all SpahQL is, is a shorthand syntax for generating traversal and descent functions, which output a proxy object for reading to and writing from the selected nodes.


I wish developers would stop copying SQL. It's like making fancy new languages, and then adding libraries that help you emulate COBOL. SQL is not the first, the last, or the best query language ever created, it's just the best marketed. It's not even properly relational, it's based on a series of shell scripts on multics for crying out loud!


"I wish developers would stop copying SQL"

This really doesn't look much like SQL to me - much more like an interesting variation on XPath...

Why do you think it is a copy of SQL?


Sorry, my comment really should have been a reply to the SQL-Like post.


Please provide some substance to your post. What other options exist? What are some references you've used to work with those options?


Well back when SQL was first created, there was a superior alternative named QUEL. Fast forward to today, and with the proliferation of programming languages that easily support high level concepts, it doesn't take that much imagination to think of better ways of dealing with large relation-values. linq for example. Going along a different direction, the language Prolog, and its much improved derivative Mercury take the concept of query languages to really amazingly awesome places. The quite well done software package PrinceXML was written in Mercury.

Edit: I also want to add Datalog http://en.wikipedia.org/wiki/Datalog

and list comprehensions http://en.wikipedia.org/wiki/List_comprehensions


The main advantage of SQL(ike) is that it is familiar, and allows a lot of people to be productive quickly.

It's a shame that QUEL lost to SQL. Betamax vs. VHS, all over again.


I'm all for empowering people to do useful work, but when you're empowering them to do stupid things that will have to be rewritten later, it's less good.


Is this not more similar to XPath?


I have used linq.js in the past to query my JSON: http://linqjs.codeplex.com/


Cool. This plus xml2js should make the whole process of extracting data from a bunch of 3rd-party xml files I'm currently dealing with a lot easier.


Hope you get some use out of it - don't forget to let me know any issues you have. Also there's some other neat JS-querying systems linked in these comments, so check those out and see which meets your needs!


Nice.

Along these lines, by the way, is my Javascript port of Apple's "key-value coding":

http://quile.github.com/keyvaluecoding-js

which allows you to traverse object graphs without all the null-check nonsense. Admittedly the purpose is slightly different, but they seem related.


Looks far too similarly pronounced to SPARQL (http://www.w3.org/TR/rdf-sparql-query/). Or is that deliberate?


Nope it's completely my fault. SpahQL is so named because it was primarily developed for Spah, another project I'm working on.

I hope I don't cause too much confusion!


Also check out json:select http://jsonselect.org/#overview It's more like css selectors than xpath


This looks interesting, I wonder whether the path syntax would work in URLs.


Can you unpack that question a little for me? As in, could you use a spahql selection as the path component of some request? I don't see why not, but the escaping will probably look a little ugly.


Given a url that returns JSON:

  www.example.com/data.json,
one could append SparQL to select a subset

  www.example.com/data.json/user

  www.example.com/data.json/categories/*

  www.example.com/data.json/categories/0/products

  www.example.com/data.json//avatar


The only small issue I can see with that is identifying where the path to the resource ends and where the query to applied to the JSON representation of the resource starts.

Perhaps something like:

    www.example.com/data.json?query=/user


A webserver could easily figure that out, as long as it is configured correctly and with knowledge of the domain. I don't like using query strings like this, as it makes the URL point to multiple objects.


I'm not sure it could, if I have a resource with a URL:

    www.example.com/foo
and it can arbitary sub-resources e.g.

    www.example.com/foo/bar/raz
then how do I know whether bar is a different resource or part of the JSON returned describing www.example.com/foo

This would mean you'd have to restrict your resource names to ensure they don't clash with JSON names - which seems a pain (e.g. say the resource names are uploaded files and directories, so you won't have much control over what they are called)


Replying to the reply to this- I am pretty sure the webserver can easily find out that foo is a JSON file when resolving the path. Most operating systems don't let you name a file and a directory the same thing, so the file system API knows straight away there is no such directory named "foo", and can have special handling for whatever kind of file "foo" happens to be. (in this case, JSON)


That's a pretty interesting idea, and I see no reason why it shouldn't work.


So, what does performance look like for complex data sets? Any benchmarks?


None whatsoever apart from to say that it's acceptably fast for whatever data set I happen to throw at it. Another poster here mentioned in an email that he'd tried it against arrays of ~50000 object structures and it was fine.


shall we add SpahQL to MongoDB?


bookmarking this.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: