Есть ли язык запросов для 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. Мы также хотим развивать его дальше, чтобы он мог служить более простой альтернативой запросам Монго.
Ответ 7
Если вы используете .NET, то Json.NET поддерживает запросы LINQ в верхней части JSON. В этом сообщении есть несколько примеров. Он поддерживает фильтрацию, сопоставление, группировку и т.д.
Ответ 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 +...
-
Еще одна интересная недавняя запись в этом пространстве называется 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.
Ответ 16
Я предпочел бы просто использовать свой собственный javascript, но для чего-то более сложного вы можете посмотреть dojo dataa > . Не использовали его, но похоже, что он дает вам примерно тот интерфейс запроса, который вы ищете.
Ответ 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>