Есть ли язык запросов для JSON? - PullRequest
202 голосов
/ 22 апреля 2009

Существует ли (примерно) SQL или XQuery-подобный язык для запросов JSON?

Я имею в виду очень маленькие наборы данных, которые хорошо отображаются в JSON, где было бы неплохо легко отвечать на запросы, такие как «каковы все значения X, где Y> 3», или выполнять обычные операции типа SUM / COUNT .

Как полностью вымышленный пример, примерно так:

[{"x": 2, "y": 0}}, {"x": 3, "y": 1}, {"x": 4, "y": 1}]

SUM(X) WHERE Y > 0     (would equate to 7)
LIST(X) WHERE Y > 0    (would equate to [3,4])

Я думаю, что это будет работать как на стороне клиента, так и на стороне сервера, при этом результаты будут преобразованы в соответствующую структуру данных для конкретного языка (или, возможно, сохранены как JSON)

Быстрый поиск в Google позволяет предположить, что люди подумали об этом и реализовали несколько вещей ( JAQL ), но пока что не появилось стандартного использования или набора библиотек. Хотя каждая функция довольно проста для реализации самостоятельно, если кто-то уже сделал это правильно, я не хочу заново изобретать колесо.

Есть предложения?

Редактировать: Это действительно может быть плохой идеей, или JSON может быть слишком универсальным форматом для того, о чем я думаю. Причина, по которой мне нужен язык запросов вместо того, чтобы просто выполнять функции суммирования / etc непосредственно по мере необходимости, заключается в том, надеюсь построить запросы динамически на основе пользовательского ввода. Вроде как аргумент, что «нам не нужен SQL, мы можем просто написать нужные нам функции». В конечном итоге это либо выходит из-под контроля, либо вы в конечном итоге пишете свою собственную версию SQL по мере продвижения вперед и дальше. (Хорошо, я знаю, что это немного глупый аргумент, но вы поняли идею ..)

Ответы [ 20 ]

3 голосов
/ 04 декабря 2012

Вот несколько простых библиотек javascript, которые также помогут:

  • Dollar Q - хорошая легкая библиотека. Он знаком с синтаксисом цепочки, популярным в jQuery, и составляет всего 373 SLOC.
  • SpahQL - это полнофункциональный язык запросов с синтаксисом, подобным XPath ( Домашняя страница , Github
  • jFunk - это язык запросов в процессе выполнения с синтаксисом, подобным селекторам CSS / jQuery. Это выглядело многообещающе, но не имело никакого развития кроме его в начальном коммите.

  • (добавлено в 2014 г.): инструмент командной строки jq имеет аккуратный синтаксис, но, к сожалению, это библиотека c. Пример использования:

    < package.json jq '.dependencies | to_entries | .[] | select(.value | startswith("git")) | .key'

3 голосов
/ 16 сентября 2015

В MongoDB , вот как это будет работать (в оболочке mongo существуют драйверы для выбранного языка).

db.collection.insert({"x": 2, "y": 0}); // notice the ':' instead of ','
db.collection.insert({"x": 3, "y": 1});
db.collection.insert({"x": 4, "y": 1});

db.collection.aggregate([{$match: {"y": {$gt: 0}}}, 
                         {$group: {_id: "sum", sum: {$sum: "$x"}}}]);
db.collection.aggregate([{$match: {"y": {$gt: 0}}}, 
                         {$group: {_id: "list", list: {$push: "$x"}}}]);

Первые три команды вставляют данные в вашу коллекцию. (Просто запустите сервер mongod и подключитесь к клиенту mongo.)

Следующие два обрабатывают данные. $match фильтры, $group применяют sum и list соответственно.

2 голосов
/ 27 января 2013

Насколько я могу судить, SpahQL является наиболее перспективным и продуманным из них. Я настоятельно рекомендую проверить это.

2 голосов
/ 30 апреля 2015
  1. У Google есть проект под названием lovefield ; только что узнал об этом, и это выглядит интересно, хотя это более сложный процесс, чем просто добавление подчеркивания или штрихов.

    https://github.com/google/lovefield

Lovefield - это механизм реляционных запросов, написанный на чистом JavaScript. Это также предоставляет помощь с сохранением данных на стороне браузера, например, используя IndexedDB для локального хранения данных. Он обеспечивает SQL-подобный синтаксис и работает кросс-браузер (в настоящее время поддерживает Chrome 37+, Firefox 31+, IE 10+ и Safari 5.1 + ...


  1. Еще одна интересная недавняя запись в этом пространстве под названием jinqJs .

    http://www.jinqjs.com/

    Краткий обзор примеров , выглядит многообещающе, и документ API выглядит хорошо написанным.


function isChild(row) {
  return (row.Age < 18 ? 'Yes' : 'No');
}

var people = [
  {Name: 'Jane', Age: 20, Location: 'Smithtown'},
  {Name: 'Ken', Age: 57, Location: 'Islip'},
  {Name: 'Tom', Age: 10, Location: 'Islip'}
];

var result = new jinqJs()
  .from(people)
  .orderBy('Age')
  .select([{field: 'Name'}, 
     {field: 'Age', text: 'Your Age'}, 
     {text: 'Is Child', value: isChild}]);

jinqJs - это небольшой, простой, легкий и расширяемый javaScript библиотека, которая не имеет зависимостей. JinqJs предоставляет простой способ выполнять SQL-подобные запросы для массивов javaScript, коллекций и веб-страниц сервисы, которые возвращают JSON-ответ. ФИЛЬМЫ ПОХОЖИЕ НА Microsoft Лямбда-выражение для .Net, и оно предоставляет аналогичные возможности коллекции запросов с использованием синтаксиса SQL и функциональности предикатов. Целью jinqJs является предоставление SQL-подобного опыта программистам знакомы с запросами LINQ.

2 голосов
/ 02 января 2014


Я только что закончил выпускную версию клиентской JS-lib (defiant.js), которая делает то, что вы ищете. С помощью defiant.js вы можете запросить структуру JSON с помощью знакомых вам выражений XPath (нет новых синтаксических выражений, как в JSONPath).

Пример того, как это работает (см. Его в браузере здесь http://defiantjs.com/defiant.js/demo/sum.avg.htm):

var data = [
       { "x": 2, "y": 0 },
       { "x": 3, "y": 1 },
       { "x": 4, "y": 1 },
       { "x": 2, "y": 1 }
    ],
    res = JSON.search( data, '//*[ y > 0 ]' );

console.log( res.sum('x') );
// 9
console.log( res.avg('x') );
// 3
console.log( res.min('x') );
// 2
console.log( res.max('x') );
// 4

Как видите, DefiantJS расширяет глобальный объект JSON функцией поиска, а возвращаемый массив доставляется с помощью агрегатных функций. DefiantJS содержит несколько других функций, но они выходят за рамки этого предмета. В любом случае, вы можете протестировать библиотеку с помощью клиентского XPath Evaluator. Я думаю, что люди, не знакомые с XPath, найдут этот оценщик полезным.
http://defiantjs.com/#xpath_evaluator

Подробнее о defiant.js
http://defiantjs.com/
https://github.com/hbi99/defiant.js

Надеюсь, вы найдете это полезным ... Привет

1 голос
/ 25 апреля 2009

Текущая реализация Jaql нацелена на обработку больших данных с использованием кластера Hadoop, так что это может быть больше, чем вам нужно. Тем не менее, он легко запускается без кластера Hadoop (но все же для компиляции требуется код Hadoop и его зависимости, которые в основном включены) Небольшая реализация Jaql, которая может быть встроена в Javascript и браузер, будет отличным дополнением к проекту.

Ваши примеры выше легко пишутся на jaql:

$data = [{"x": 2, "y": 0}, {"x": 3, "y": 1}, {"x": 4, "y": 1}];

$data -> filter $.y > 0 -> transform $.x -> sum(); // 7

$data -> filter $.y > 0 -> transform $.x; // [3,4]

Конечно, есть еще много чего. Например:

// Compute multiple aggregates and change nesting structure:
$data -> group by $y = $.y into { $y, s:sum($[*].x), n:count($), xs:$[*].x}; 
    // [{ "y": 0, "s": 2, "n": 1, "xs": [2]   },
    //  { "y": 1, "s": 7, "n": 2, "xs": [3,4] }]

// Join multiple data sets:
$more = [{ "y": 0, "z": 5 }, { "y": 1, "z": 6 }];
join $data, $more where $data.y == $more.y into {$data, $more};
    // [{ "data": { "x": 2, "y": 0 }, "more": { "y": 0, "z": 5 }},
    //  { "data": { "x": 3, "y": 1 }, "more": { "y": 1, "z": 6 }},
    //  { "data": { "x": 4, "y": 1 }, "more": { "y": 1, "z": 6 }}]

Jaql можно скачать / обсудить на http://code.google.com/p/jaql/

1 голос
/ 12 июня 2015

Когда бы ни было возможно, я бы переместил все запросы к серверной части сервера (к базе данных SQL или другому собственному типу базы данных). Причина в том, что это будет быстрее и более оптимизировано для выполнения запросов.

Я знаю, что jSON может быть автономным и может существовать +/- для языка запросов, но я не вижу преимущества, если вы извлекаете данные из серверной части в браузер, как в большинстве случаев использования JSON. Запросите и отфильтруйте на сервере, чтобы получить как можно меньше нужных данных.

Если по какой-либо причине вам нужно выполнить запрос на внешнем интерфейсе (в основном в браузере), я бы предложил просто использовать array.filter (зачем придумывать что-то еще?).

Тем не менее, я думаю, что более полезным будет API преобразования для json ... они более полезны, поскольку, получив данные, вы захотите их отобразить несколькими способами. Однако, опять же, вы можете сделать многое из этого на сервере (что может быть гораздо проще масштабировать), чем на клиенте - ЕСЛИ вы используете серверную <-> модель клиента.

Только моя стоимость в 2 пенса!

1 голос
/ 25 мая 2014

Вы также можете использовать Underscore.js , который является в основном библиотекой швейцарского ножа для управления коллекциями. Используя _.filter, _.pluck, _.reduce, вы можете выполнять SQL-подобные запросы.

var data = [{"x": 2, "y": 0}, {"x": 3, "y": 1}, {"x": 4, "y": 1}];

var posData = _.filter(data, function(elt) { return elt.y > 0; });
// [{"x": 3, "y": 1}, {"x": 4, "y": 1}]

var values = _.pluck(posData, "x");
// [3, 4]

var sum = _.reduce(values, function(a, b) { return a+b; });
// 7

Underscore.js работает как на стороне клиента, так и на стороне сервера, и является заметной библиотекой.

Вы также можете использовать Lo-Dash , который является форком Underscore.js с лучшими характеристиками.

1 голос
/ 22 апреля 2009

Я поддержу идею использования вашего собственного javascript, но для чего-то более сложного вы можете взглянуть на данные dojo . Не использовал его, но, похоже, он дает вам примерно тот интерфейс запроса, который вы ищете.

0 голосов
/ 01 мая 2019

Выезд https://github.com/niclasko/Cypher.js (примечание: я автор)

Это реализация Javascript с нулевой зависимостью языка запросов базы данных графов Cypher вместе с базой данных графов. Работает в браузере (протестировано с Firefox, Chrome, IE).

С учетом вопроса. Может использоваться для запроса конечных точек JSON:

load json from "http://url/endpoint" as l return l limit 10

Вот пример запроса сложного документа JSON и выполнения анализа на нем:

Пример запроса JSON Cypher.js

...