Есть ли язык запросов для JSON?

Есть ли (грубо) 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)

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

Любые предложения?

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

Ответ 1

Конечно, как насчет:

Все они, похоже, немного работают, но работают в некоторой степени. Они также похожи на XPath и XQuery концептуально; хотя XML и JSON имеют разные концептуальные модели (иерархические vs object/struct).

EDIT Sep-2015: На самом деле теперь существует стандарт JSON Pointer, который позволяет очень просто и эффективно обходить содержимое JSON. Он не только формально определен, но также поддерживается многими библиотеками JSON. Поэтому я бы назвал это реальным реальным полезным стандартом, хотя из-за его ограниченной выразительности он может или не может считаться языком запросов как таковой.

Ответ 2

Я бы порекомендовал свой проект, над которым я работаю над jLinq. Я ищу обратную связь, поэтому мне было бы интересно узнать, что вы думаете.

Если вы можете писать запросы, похожие на то, как вы бы в LINQ...

var results = jLinq.from(records.users)

    //you can join records
    .join(records.locations, "location", "locationId", "id")

    //write queries on the data
    .startsWith("firstname", "j")
    .or("k") //automatically remembers field and command names

    //even query joined items
    .equals("location.state", "TX")

    //and even do custom selections
    .select(function(rec) {
        return {
            fullname : rec.firstname + " " + rec.lastname,
            city : rec.location.city,
            ageInTenYears : (rec.age + 10)
        };
    });

Он полностью расширяемый!

Документация по-прежнему выполняется, но вы все равно можете попробовать ее в Интернете.

Ответ 3

Обновление: XQuery 3.1 может запрашивать либо XML, либо JSON, либо оба вместе. И XPath 3.1 тоже может.

Список растет:

Ответ 4

jmespath работает очень легко и хорошо, http://jmespath.org/ Он используется Amazon в интерфейсе командной строки AWS, поэтому он должен быть достаточно стабильным.

Ответ 5

Встроенный метод array.filter() делает большинство из этих так называемых библиотек запросов javascript устаревшими

Вы можете добавить в делегат столько условий, сколько можете себе представить: простое сравнение, startWith и т.д. Я не тестировал, но вы, вероятно, могли бы также фильтровать фильтры для запросов внутренних коллекций.

Ответ 6

ObjectPath - это простой и лёгкий язык запросов для документов JSON сложной или неизвестной структуры. Он похож на XPath или JSONPath, но гораздо более мощный благодаря встроенным арифметическим вычислениям, механизмам сравнения и встроенным функциям.

Example

Версия Python является зрелой и используется в производстве. JS все еще находится в бета-версии.

Вероятно, в ближайшее время мы предоставим полноценную версию Javascript. Мы также хотим развивать его дальше, чтобы он мог служить более простой альтернативой запросам Монго.

Ответ 8

Другой способ посмотреть на это - использовать mongoDB. Вы можете сохранить свой JSON в mongo, а затем запросить его с помощью синтаксиса запроса mongodb.

Ответ 9

JQ является SON д языка uery J, в основном предназначен для командной строки, но с креплениями для широкого спектра языков программирования (Java, Node.js, PHP,...) и доступны даже в браузере через JQ-сеть.

Вот несколько иллюстраций, основанных на оригинальном вопросе, который привел этот JSON в качестве примера:

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

СУММА (X) ГДЕ Y> 0 (будет равно 7)

map(select(.y > 0)) | add

СПИСОК (X) ГДЕ Y> 0 (будет соответствовать [3,4])

map(.y > 0)

Синтаксис JQ расширяет синтаксис JSON

Каждое выражение JSON является допустимым выражением jq, а такие выражения, как [1, (1+1)] и {"a": (1 + 1)} ', иллюстрируют, как jq расширяет синтаксис JSON.

Более полезным примером является выражение jq:

{a,b}

который, учитывая значение JSON {"a":1, "b":2, "c": 3}, оценивается как {"a":1, "b":2}.

Ответ 10

ОК, этот пост немного старый, но... если вы хотите выполнить SQL-подобный запрос в собственных JSON-объектах (JS-объектах) на объектах JS, посмотрите https://github.com/deitch/searchjs

Это язык jsql, полностью написанный в JSON, и эталонная реализация. Вы можете сказать: "Я хочу найти весь объект в массиве с name= ==" John "& age === 25 as:

{name:"John",age:25,_join:"AND"}

Эталонная реализация searchjs работает как в браузере, так и в пакете node npm

npm install searchjs

Он также может делать такие вещи, как сложные объединения и отрицание (NOT). Это изначально игнорирует случай.

Он еще не суммирует или не подсчитывает, но, вероятно, легче сделать это снаружи.

Ответ 11

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

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

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

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

Ответ 12

В 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 соответственно.

Ответ 13

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

Ответ 14


Я только что закончил выпущенную версию клиентской 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 содержит несколько других функций, но они не подходят для этого предмета. Anywho, вы можете протестировать lib с клиентом XPath Evaluator. Я думаю, что люди, не знакомые с XPath, найдут этот оценщик полезным.
http://defiantjs.com/#xpath_evaluator

Дополнительная информация о defiant.js
http://defiantjs.com/
https://github.com/hbi99/defiant.js

Надеюсь, вы сочтете это полезным... Отношения

Ответ 15

  • У Google есть проект под названием lovefield; только что узнал об этом, и он выглядит интересным, хотя он более активен, чем просто опускание подчеркивания или lodash.

    https://github.com/google/lovefield

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


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

    http://www.jinqjs.com/

    Кратко рассмотрев examples, он выглядит многообещающим, а Документ 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. jinqJs похожа на Microsoft Lambda выражение для .Net, и он предоставляет аналогичные возможности для коллекций запросов с использованием синтаксиса SQL и функций предикатов. Цель jinqJss - предоставить SQL-программисту опыт знакомы с запросами LINQ.

Ответ 17

Текущая реализация 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/

Ответ 18

Вы также можете использовать 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 с лучшими характеристиками.

Ответ 19

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

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

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

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

Просто мой 2 пенсов стоит!

Ответ 20

Проверьте 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

Ответ 21

Вы можете использовать linq.js

Это позволяет использовать агрегаты и выборки из набора данных объектов, как данные других структур.

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

// SUM(X) WHERE Y > 0     -> 7
console.log(Enumerable.From(data).Where("$.y > 0").Sum("$.x"));

// LIST(X) WHERE Y > 0    -> [3, 4]
console.log(Enumerable.From(data).Where("$.y > 0").Select("$.x").ToArray());
<script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>