2017-10-28 73 views
1

我想用JSONiq计数重复值。我有下面的代码:JSONiq计数重复数组

jsoniq version "1.0"; 

import module namespace fetch = "http://zorba.io/modules/fetch"; 

let $tweets := parse-json(fetch:content("/tweets.json")) 
let $users := parse-json(fetch:content("/users.json")) 

return 
    let $different_languages := 
     for $tweet in $tweets[] 
     return { 
      "name" : $tweet."metadata"."iso_language_code" 
     } 


    return [$different_languages] 

这将返回所有的语言,但它打开了每一种语言一双新鞋。它看起来像这样:

[ { "name" : "de" }, 
     { "name" : "da" }, 
     { "name" : "da" }, 
     { "name" : "da" }] 

我想回到一个JSON对象,看起来像这样:

[ { "count" : 1, "language" : "de" }, 
     { "count" : 3, "language" : "da" }] 

我怎样才能做到这一点?

回答

1

这可以通过分组子句来实现。这可以像SQL组一样工作,但具有更好的控制级别。

在下面的代码中,拆箱$tweets阵列中的四个对象根据其语言字段($tweet.metadata.iso_language_code)进行分组。在返回子句的每次评估中,分组变量$language将包含当前组语言的名称,非分组变量$tweet将包含属于该组的推文序列。在这个序列上调用count()将分别返回3和1。

jsoniq version "1.0"; 

import module namespace fetch = "http://zorba.io/modules/fetch"; 

let $tweets := parse-json(fetch:content("/tweets.json")) 
let $users := parse-json(fetch:content("/users.json")) 

return 
    for $tweet in $tweets[] 
    group by $language := $tweet."metadata"."iso_language_code" 
    return { language: $language, count: count($tweet) } 

另外,也没有必要在metadataiso_language_code引号。如果需要的话,你也可以换,结果到一个数组,像这样:

jsoniq version "1.0"; 

import module namespace fetch = "http://zorba.io/modules/fetch"; 

let $tweets := parse-json(fetch:content("/tweets.json")) 
let $users := parse-json(fetch:content("/users.json")) 

return [ 
    for $tweet in $tweets[] 
    group by $language := $tweet.metadata.iso_language_code 
    return { language: $language, count: count($tweet) } 
] 

上有回报子句中的表达没有限制:$language$tweet就像任何其他变量,它们可以被用来作为输入到任何JSONiq表达式。例如,代替计算推文,也可以将它们嵌套在输出中,因为数据模型是树状的:

return { language: $language, count: [ $tweet ] }