JSON에 대한 쿼리 언어가 있습니까?


227

JSON 쿼리를위한 (거의) SQL 또는 XQuery와 유사한 언어가 있습니까?

"X의 모든 값이 Y> 3"과 같은 쿼리에 쉽게 응답하거나 일반적인 SUM / COUNT 유형 작업을 수행하는 것과 같은 쿼리에 JSON에 잘 매핑되는 매우 작은 데이터 세트를 생각하고 있습니다.

완전히 구성된 예제로 다음과 같습니다.

[{"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으로 유지 될 것이라고 생각합니다.

빠른 인터넷 검색은 사람들이 그것에 대해 생각하고 몇 가지 ( JAQL )를 구현했다고 제안 하지만 표준 사용법이나 라이브러리 세트가 아직 등장하지 않은 것 같습니다. 각 기능은 자체적으로 구현하는 것이 쉽지 않지만 누군가가 이미 올바르게 수행 한 경우 바퀴를 다시 발명하고 싶지 않습니다.

어떤 제안?

편집 : 이것은 실제로 나쁜 생각 일 수도 있고 JSON이 너무 일반적인 형식 일 수도 있습니다. 필요에 따라 합산 등을 직접 수행하는 대신 쿼리 언어를 원하는 이유는 빌드하기를 희망하기 때문입니다. 사용자 입력에 따라 동적으로 쿼리합니다. "우리는 SQL이 필요하지 않고 필요한 함수를 작성할 수있다"는 주장을 좋아한다. 결국 손이 닿지 않거나 더 많은 SQL을 밀어 넣을 때 자신 만의 SQL 버전을 작성하게됩니다. (좋아, 나는 그것이 약간 바보 같은 주장이라는 것을 알고 있지만, 당신은 아이디어를 얻는다.)


나도 그런 필요가있다. 객체 트리의 특정 위치에서 특정 값으로 들어오는 JSON 요청을 일치시켜야합니다. 쿼리는 실제로 (고급) 사용자가 구성해야합니다. 현재 해결 방법은 JSON으로 임시 XML을 작성하고 XPath를 적용하는 것입니다.
Vladimir Dyuzhev

1
쉘 도구에 가깝지만 jq ( stedolan.github.io/jq )는 json 데이터를 탐색하는 데 훌륭했습니다. 놀이터에서 그것을 밖으로 시도 : jqplay.org
jtmoulia

sqall.co의 공개 JSON 피드 또는 API에서 SQL 쿼리를 실행할 수있는 웹 기반 도구가 있습니다 .
Stack Man


에서 더 많은 아이디어 stackoverflow.com/questions/1955505/...
wisbucky

답변:


91

물론 어떻습니까 :

그들은 모두 약간의 작업이 진행되는 것처럼 보이지만 어느 정도 작동합니다. 또한 XPath 및 XQuery와 개념적으로 유사합니다. XML과 JSON에는 다른 개념적 모델이 있지만 (hierarchic와 객체 / 구조).

2015 년 9 월 편집 : 실제로 JSON 콘텐츠를 매우 간단하고 효율적으로 통과 할 수있는 JSON 포인터 표준이 있습니다. 공식적으로 지정 될뿐만 아니라 많은 JSON 라이브러리에서도 지원됩니다. 따라서 표현력이 제한되어 있기 때문에 쿼리 언어 자체로 간주 될 수도 있고 그렇지 않을 수도 있지만 실제 실제 유용한 표준이라고 부릅니다.


77
다시 말해서, 표준적이고 안정적인 것은 없습니다 ... :-(
Vladimir Dyuzhev

표준에 대해 이야기하면서 XQuery 3.1이 JSON 쿼리를 지원하도록 확장 될 수 있다는 소문을 들었습니다 ( JSONiq 와 유사 ). 물론 XQuery 3.0이 아직 공식적으로 출시되지 않았기 때문에 다소 시간이 걸릴 수 있습니다.
Julien Ribon

자비, 나는 분명히 희망하지 않습니다. 내가 본 모든 XML-> JSON 시도는 끔찍한 혼란이었다. 정보 모델은 호환되지 않는다. 그러나 나는 동일한 아이디어, 구문의 일부를 사용하여 JQuery를보고 싶다. JSON 정보 모델로 올바르게 수정되었습니다.
StaxMan

1
JSONPath의 Ruby 구현을 찾는 사람은 github.com/joshbuddy/jsonpath
Robert Ross

@ GôTô : MongoDB를 사용하면 자유가 있다면 실행 가능한 접근법처럼 보입니다. ( 쿼리를 내장 쉘로 변환하는 방법에 대한 예는 아래 답변을 참조하십시오 )
serv-inc

48

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)
        };
    });

완전히 확장 가능합니다!

설명서가 아직 진행 중이지만 온라인으로 계속 시도 할 수 있습니다.


@hugoware : 이것에 대한 문서가 있습니까? .starts () 이외의 쿼리가 있습니까 (예 : contains?)
Rikki

5
8 년 전 마지막 업데이트로 5 년 전에 프로젝트가 종료되었는지 여부에 대한 응답이 없습니다 ... 프로젝트가 종료 된 것 같습니다.
cfc

36

업데이트 : XQuery 3.1 은 XML 또는 JSON 중 하나 또는 둘 다를 쿼리 할 수 ​​있습니다. 그리고 XPath 3.1 도 가능합니다.

목록이 늘어나고 있습니다.


14

jmespath는 아주 쉽고 잘 작동합니다. http://jmespath.org/ Amazon은 AWS 명령 줄 인터페이스에서 사용하고 있으므로 매우 안정적입니다.


5
그러나 같은 페이지에서 동시에 : "--query로 불가능한 고급 기능이 필요한 경우 명령 행 JSON 프로세서 인 jq를 확인할 수 있습니다." 이 AWS 사용하는 것 같습니다 그래서 jmespath에 대한 --query매개 변수 만 권장 jq명령 줄 배관. docs.aws.amazon.com/cli/latest/userguide/…
wisbucky 2014

10

JQ는 A는 J 아들 Q의 주로를 통해 브라우저에서도 사용할 수 프로그래밍 언어 (자바, Node.js를, PHP, ...)과의 광범위한 명령 줄뿐만 바인딩으로 구성 uery 언어, JQ-웹 .

다음은 원래 질문을 기반으로 한 몇 가지 예입니다.이 JSON은 예제입니다.

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

합 (X) WYE> 0 (7과 같음)

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

LIST (X) 여기서 Y> 0 ([3,4]와 동일)

map(.y > 0)

jq 구문은 JSON 구문을 확장합니다

모든 JSON 표현식은 유효한 jq 표현식이며 and [1, (1+1)]{ "a": (1 + 1)}`와 같은 표현식 은 jq가 JSON 구문을 확장하는 방법을 보여줍니다.

더 유용한 예는 jq 표현식입니다.

{a,b}

JSON 값이 주어지면로 {"a":1, "b":2, "c": 3}평가됩니다 {"a":1, "b":2}.


8

내장 된 array.filter()메소드 는 이러한 소위 자바 스크립트 쿼리 라이브러리를 대부분 사용하지 않습니다.

간단한 비교, startsWith 등 내가 상상할 수있는 한 많은 조건을 대리자 안에 넣을 수 있습니다. 테스트하지는 않았지만 내부 컬렉션을 쿼리하기 위해 필터를 중첩 할 수도 있습니다.


5
array.filter()JSON이 아닌 JavaScript의 일부입니다.
Iain Samuel McLean Elder

2
JSON은 JavaScript의 하위 집합이지만 JSON과 배열을 모두 지원하고 배열 필터 방법이 구현 된 언어가 많으므로 이것이 유효한 지점입니다.
dakab

7

.NET을 사용하는 경우 Json.NET 은 JSON 위에서 LINQ 쿼리를 지원합니다. 이 게시물 에는 몇 가지 예가 있습니다. 필터링, 매핑, 그룹화 등을 지원합니다.


7

ObjectPath 는 구조가 복잡하거나 알려지지 않은 JSON 문서를위한 단순하고 간단한 쿼리 언어입니다. XPath 또는 JSONPath와 비슷하지만 내장 된 산술 계산, 비교 메커니즘 및 내장 함수 덕분에 훨씬 강력합니다.

예

파이썬 버전은 성숙하여 프로덕션 환경에서 사용됩니다. JS는 아직 베타 버전입니다.

아마도 가까운 시일 내에 본격적인 Javascript 버전을 제공 할 것입니다. 또한 몽고 쿼리에 대한 간단한 대안으로 사용할 수 있도록 추가로 개발하고 싶습니다.


1
문서가 거의 없기 때문에 텍스트와 같은 요소가있는 요소를 찾는 방법을 찾는 것은 어렵습니다.
James O'Brien 1

1
@ JamesO'Brien 의견을 보내 주셔서 감사합니다. 참조가 쓸모없고 특정 문제를 염두에두고 있으면 여기에 알려주십시오 . 누군가 도와 주려고 노력할 것입니다. 현재 문서를보다 유용하게 만들기 위해 노력하고 있습니다. 귀하의 의견을 환영합니다.
엘라 베드

감사합니다-고맙습니다. 사용하고 싶습니다. 현재 ashphy.com/JSONPathOnlineEvaluator를 사용 하고 있습니까?
제임스 오브라이언

문서가 부족하여 Javascript와 함께 이것을 사용하는 방법을 알 수 없습니다.
user3670743

우리는 그 일을 도울 기고자를 찾고 있습니다. Github 또는 Google 그룹스 groups.google.com/forum/#!members/objectpath 에 달성하려는 내용을 쓸 수 있으며 누군가 Q에 대답 할 것이라고 확신합니다.
Ela Bednarek

6

이것을 보는 또 다른 방법은 mongoDB 를 사용하는 것입니다. JSON을 mongo에 저장 한 다음 mongodb 쿼리 구문을 통해 쿼리 할 수 ​​있습니다.


MongoDB는 사용하기에 매우 좋습니다. 사용 방법에 대한 예는 아래 답변을 참조하십시오 .
serv-inc

4

좋아,이 게시물은 조금 오래되었지만 ... JS 객체의 기본 JSON (또는 JS 객체)에서 SQL과 같은 쿼리를 수행 하려면 https://github.com/deitch/searchjs를 살펴보십시오.

JSON으로 완전히 작성된 jsql 언어이며 참조 구현입니다. "name ==="John "&& age === 25 인 배열에서 모든 객체를 찾고 싶습니다.

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

참조 구현 searchjs는 노드 npm 패키지뿐만 아니라 브라우저에서도 작동합니다.

npm install searchjs

복잡한 조인 및 부정 (NOT)과 같은 작업도 수행 할 수 있습니다. 기본적으로 대소 문자를 무시합니다.

아직 합산이나 계산을 수행하지는 않지만 외부에서 수행하는 것이 더 쉽습니다.


3

트릭을 수행하는 간단한 자바 스크립트 라이브러리는 다음과 같습니다.

  • Dollar Q 는 훌륭한 경량 라이브러리입니다. jQuery가 널리 사용하는 체인 구문에 익숙한 느낌을 주며 373 SLOC에 불과합니다.
  • SpahQL 은 XPath ( Homepage , Github 와 유사한 구문을 가진 완전한 기능을 갖춘 쿼리 언어입니다.
  • jFunk 는 CSS / jQuery 선택기와 유사한 구문을 사용하여 진행중인 쿼리 언어입니다. 유망한 것처럼 보였지만 초기 커밋을 넘어서는 개발은 없었습니다.

  • (2014 추가) : jq 명령 줄 도구 에는 깔끔한 구문이 있지만 불행히도 ac 라이브러리입니다. 사용법 예 :

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


3

에서 MongoDB를 이는합니다 (몽고 쉘에서, 당신의 선택의 언어에 대한 드라이버가 존재한다) 일 것입니다 방법이다.

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

SpahQL은 내가 알 수있는 한, 가장 유망하고 잘 생각됩니다. 확인하는 것이 좋습니다.


2


방금 찾고있는 클라이언트 측 JS-lib (defiant.js)의 릴리스 가능한 버전을 완료했습니다. defiant.js를 사용하면 익숙한 XPath 표현식을 사용하여 JSON 구조를 쿼리 할 수 ​​있습니다 (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를 사용하여 lib를 테스트 할 수 있습니다. XPath에 익숙하지 않은 사람들은이 평가자가 유용하다고 생각합니다.
http://defiantjs.com/#xpath_evaluator

defiant.js에 대한 추가 정보
http://defiantjs.com/
https://github.com/hbi99/defiant.js

도움이 되셨기를 바랍니다. 감사합니다.


현재 결과의 전체 경로를 얻을 수 있습니까?
XeniaSis

2
  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는 의존성이없는 작고 단순하며 가볍고 확장 가능한 자바 스크립트 라이브러리입니다. jinqJ는 JSON 응답을 반환하는 javaScript 배열, 컬렉션 및 웹 서비스에서 SQL과 같은 쿼리를 수행하는 간단한 방법을 제공합니다. jinqJ는 Microsoft의 .Net 용 Lambda 식과 유사하며 SQL과 같은 구문 및 조건 자 기능을 사용하여 컬렉션을 쿼리하는 비슷한 기능을 제공합니다. jinqJs의 목적은 LINQ 쿼리에 익숙한 프로그래머에게 SQL과 같은 경험을 제공하는 것입니다.


1

나는 당신 자신의 자바 스크립트를 사용한다는 개념을 두 번째로 설명하지만, 좀 더 정교한 것을 위해 dojo data를 볼 수 있습니다 . 그것을 사용하지는 않았지만 대략 원하는 종류의 쿼리 인터페이스를 제공하는 것처럼 보입니다.


1

현재 Jaql 구현은 Hadoop 클러스터를 사용하여 대용량 데이터 처리를 대상으로하므로 필요한 것 이상일 수 있습니다. 그러나 Hadoop 클러스터 없이도 쉽게 실행할 수 있습니다 (그러나 여전히 포함되는 Hadoop 코드 및 해당 종속성을 컴파일해야 함). Javascript와 브라우저에 내장 될 수있는 Jaql의 작은 구현은 프로젝트에 큰 도움이 될 것입니다.

위의 예는 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

기본적으로 스위스 나이프 라이브러리 인 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는 클라이언트 측과 서버 측 모두에서 작동하며 주목할만한 라이브러리입니다.

Underscore.js의 포크 인 Lo-Dash 를 더 나은 성능으로 사용할 수도 있습니다 .


1

가능할 때마다 모든 쿼리를 서버의 백엔드 (SQL DB 또는 기타 기본 데이터베이스 유형)로 이동합니다. 이유는 쿼리를 수행하는 것이 더 빠르고 더 최적화되어 있기 때문입니다.

jSON은 독립형 일 수 있으며 쿼리 언어가 +/-있을 수 있지만 대부분의 JSON 사용 사례와 같이 백엔드에서 브라우저로 데이터를 검색하는 경우 이점을 볼 수 없습니다. 백엔드에서 쿼리 및 필터링하여 필요한 작은 데이터를 얻습니다.

어떤 이유로 든 프론트 엔드 (대부분 브라우저)에서 쿼리 해야하는 경우 array.filter를 사용하는 것이 좋습니다 (왜 다른 것을 발명 했습니까?).

내가 더 유용하다고 생각하는 것은 json을위한 변환 API입니다 ... 데이터가 일단 있으면 여러 가지 방법으로 표시 할 수 있기 때문에 더 유용합니다. 그러나 다시 서버에서 클라이언트보다 서버를 확장 할 수있는 많은 작업을 수행 할 수 있습니다 (server <-> client 모델을 사용하는 경우).

내 2 펜스 가치!


1

https://github.com/niclasko/Cypher.js를 확인 하십시오 (참고 : 저자입니다).

Cypher 그래프 데이터베이스 쿼리 언어와 그래프 데이터베이스의 제로 의존성 Javascript 구현입니다. 브라우저에서 실행됩니다 (Firefox, Chrome, IE에서 테스트).

질문과 관련이 있습니다. JSON 끝점을 쿼리하는 데 사용할 수 있습니다.

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

복잡한 JSON 문서를 쿼리하고 이에 대한 분석을 수행하는 예는 다음과 같습니다.

Cypher.js JSON 쿼리 예


1

PythonQL가 IMHO는 SQL에 대한 개선 것을 포함 된 구문을 제공 주로하기 때문에 group, window, where, let, 등을 자유롭게 혼합 할 수 있습니다.

$ cat x.py
#coding: pythonql
data = [{"x": 2, "y": 0}, {"x": 3, "y": 1}, {"x": 4, "y": 1}]
q = [x match {'x': as x, 'y': as y} in data where y > 0]
print(sum(q))
print(list(q))

q = [x match {'x': as x, 'y': as y} as d in data where d['y'] > 0]
print(sum(q))

이 코드는 전체 구조를 처리해야하거나 값만 처리해야하는지에 따라 두 가지 다른 답변을 보여줍니다. 실행은 예상 결과를 제공합니다.

$ python x.py
7
[3, 4]
7

0

사용할 수 있습니다 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>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.