demo 解读

本文的主要目的是整理梳理对于jolt json的使用,主要使用场景就是json mapping

模式的含义

  • shift 清空后输出
  • default 直接输出,类似于增量
* 匹配所有
& 取key值	    出现在value里 	    例子:&=&0当前层级  &1向上1级		value里没有能力获取key值但是可以通过*,$配合使用
$ 取key值	    出现在key里		    同上
@ 取value值	    出现在key里		    例子:@(3,clientId)  @取value值 {{{从上往下3级,到clientId,hidden,取clientId的值
# 固定输出值	出现在key里或value里

盗梦空间 - Inception

josn input

{
  "rating": {
    "primary": {
      "value": 3
    },
    "quality": {
      "value": 3
    }
  }
}

json spec

[
  {
  //shfit清空后输出
    "operation": "shift",
    "spec": {
      "rating": {
        "primary": {
          // 获取rating.primary.value值 重命名为Rating
          "value": "Rating"
        },
        // *表示匹配所有json数据,*优先级最低,却明确越优先,所有下面不会处理primary
        "*": {
          // &1 means, go up one level and grab that value and substitute it in
          // &1表示,向上一级,获取那个值并代入
          // 下面这个场景 &1 = "quality"
          //SecondaryRatings就是命名的一个固定的字段而已,Value也是
          //SecondaryRatings.quality.Value=3
          "value": "SecondaryRatings.&1.Value",
         
          // "$"表示把input中json的key拿过来
          "$": "SecondaryRatings.&1.Id"
        }
      }
    }
  },
  {
  //default直接输出,类似于增量
    "operation": "default",
    "spec": {
      "Range": 5,
      "SecondaryRatings": {
        "*": {
          // SecondaryRatings下都会加上ChildRange=5
          "ChildRange": 5
        }
      }
    }
  }
]

json output

{
  "Rating" : 3,
  "SecondaryRatings" : {
    "quality" : {
      "Id" : "quality",
      "Value" : 3,
      "ChildRange" : 5
    }
  },
  "Range" : 5
}

给所有key添加rating-前缀 - Convert nested data, to 'prefix soup'.

json input

{
  "Rating": 1,
  "SecondaryRatings": {
    "Design": 4,
    "Price": 2,
    "RatingDimension3": 1
  }
}

json spec

[
  {
    "operation": "shift",
    "spec": {
    //Rating重命名为rating-primary
    //rating-primary=1
      "Rating": "rating-primary",
      // 将所有二级评级转换为前缀数据
      "SecondaryRatings": {
        //&表示&0,也就是向上0级,就是当前级
        "*": "rating-&"
      }
    }
  }
]

json output

{
  "rating-primary" : 1,
  "rating-Design" : 4,
  "rating-Price" : 2,
  "rating-RatingDimension3" : 1
}

一级结构根据key规则转换为多级结构 - Convert 'prefix soup', to nested data.

json input

{
  "rating-primary": 1,
  "rating-Price": 2,
  "rating-Design": 4,
  "rating-RatingDimension3": 1
}

json spec

[
  {
    "operation": "shift",
    "spec": {
      // rating-primary重命名为 Rating
      "rating-primary": "Rating",
      // 剩下的rating-
      //SecondaryRatings.是固定值
      //"rating-*": "Ratings2.&",
      //&是获取当前级key,也就是rating-Price,rating-Design,rating-RatingDimension3
      //这时我想去掉key中rating-,变成Price,Design,RatingDimension3
      "rating-*": "Ratings3.&(0,1)"
    }
  }
]

json output

{
  "Rating" : 1,
  "SecondaryRatings" : {
    "Price" : 2,
    "Design" : 4,
    "RatingDimension3" : 1
  }
}

获取LHS键值 - Grab LHS key values.

json input

{
  "rating": {
    "primary": {
      "value": 3,
      "max": 5
    },
    "quality": {
      "value": 3,
      "max": 7
    }
  }
}

json spec

[
  {
    "operation": "shift",
    "spec": {
      "rating": {
      //匹配rating下面一级,也就是primary,quality
        "*": {
          //输出成ratingNames的一个数组
          //key都是通过$,也就是$0获取得来, $=primary,quality
          "$": "ratingNames[]"
          //$1=rating
        }
      }
    }
  }
]

json output

{
  "ratingNames" : [ "primary", "quality" ]
}

Map(key-value)转List(数组) - Map to list.

json input

{
  "ratings": {
    "primary": 5,
    "quality": 4,
    "design": 5
  }
}

json spec

[
  {
    "operation": "shift",
    "spec": {
      "ratings": {
        "*": {
          // #2 means go three levels up the tree (count from 0),
          //  and ask the "ratings" node, how many of it's
          //  children have been matched.
          //
          // This allows us to put the Name and the Value into
          //  the same object in the Ratings array.
          //$=$0当前层级primary,quality,design
          //#2表示向上移动三层(从0开始计数),
          //Ratings[]定义一个数组
          //数组两个变量Name和Value
          //@取value
          "$": "Ratings[#2].Name",
          "@": "Ratings[#2].Value"
          //自己推到一下
          //"$": "Ratings[]"        "Ratings" : [ "primary", "quality", "design" ]
          //"$": "Ratings[].test"    "Ratings" : [ {
          //                              "test" : "primary"
        //                              }, {
         //                               "test" : "quality"
          //                            }, {
        //                                "test" : "design"
         //                             } ]
         //"$": "Ratings[#].test"           {
         //                                     "Ratings" : [ {
         //                                       "test" : [ "primary", "quality", "design" ]
          //                                    } ]
        //                                    }
        //
         //#=#0=#1
         //Ratings[#2].test             {
         //                                 "Ratings" : [ {
          //                                  "test" : "primary"
        //                                  }, {
         //                                   "test" : "quality"
          //                                }, {
        //                                    "test" : "design"
         //                                 } ]
          //                              }
        
          //  "$": "Ratings[#2].Name",
          //"@": "Ratings[#2].Value"          {
        //                                  "Ratings" : [ {
         //                                   "Name" : "primary",
          //                                  "Value" : 5
        //                                  }, {
         //                                   "Name" : "quality",
          //                                  "Value" : 4
        //                                  }, {
         //                                   "Name" : "design",
         //                                   "Value" : 5
         //                                 } ]
         //                               }
         //   "$": "Ratings[].Name",
         //  "@": "Ratings[].Value"            {
        //                                      "Ratings" : [ {
         //                                       "Name" : "primary"
         //                                     }, {
         //                                       "Value" : 5
         //                                     }, {
         //                                       "Name" : "quality"
         //                                     }, {
         //                                       "Value" : 4
         //                                    }, {
         //                                       "Name" : "design"
         //                                     }, {
         //                                       "Value" : 5
         //                                     } ]
         //                                   }
         //   "$": "Ratings[#].Name",
         // "@": "Ratings[#].Value"           {
         //                                     "Ratings" : [ {
         //                                       "Name" : [ "primary", "quality", "design" ],
         //                                       "Value" : [ 5, 4, 5 ]
         //                                     } ]
         //                                   }
            //#=#0=#1
            
            

        }
      }
    }
  }
]

json output

{
  "Ratings" : [ {
    "Name" : "primary",
    "Value" : 5
  }, {
    "Name" : "quality",
    "Value" : 4
  }, {
    "Name" : "design",
    "Value" : 5
  } ]
}

List(array) to Map(key value) - List to Map.

json input

{
  "Photos": [
    {
      "Id": "327703",
      "Caption": "TEST>> photo 1",
      "Url": "http://bob.com/0001/327703/photo.jpg"
    },
    {
      "Id": "327704",
      "Caption": "TEST>> photo 2",
      "Url": "http://bob.com/0001/327704/photo.jpg"
    }
  ]
}

json spec

[
  // 平铺
  {
    "operation": "shift",
    "spec": {
      "Photos": {
        "*": {
        //&1 取到的是数组的下标
          "Id": "photo-&1-id",
          "Caption": "photo-&1-caption",
          "Url": "photo-&1-url"
        }
      }
    }
  }
]

json output

{
  "photo-0-id" : "327703",
  "photo-0-caption" : "TEST>> photo 1",
  "photo-0-url" : "http://bob.com/0001/327703/photo.jpg",
  "photo-1-id" : "327704",
  "photo-1-caption" : "TEST>> photo 2",
  "photo-1-url" : "http://bob.com/0001/327704/photo.jpg"
}

对象属性转map(key value)- On a match, apply a String default.

json input

{
  "data" : {
    "1234": {
      "clientId": "12",
      "hidden": true
    },
    "1235": {
      "clientId": "35",
      "hidden": false
    }
  }
}

json spec

[
  {
    "operation": "shift",
    "spec": {
      "data": {
        "*": {
          "hidden": {
          //value也可以写在这里的
            "true": {
              //clients固定
              //@(3,clientId)  @取value值 *所以从data开始 data.xxx.clientId从上往下3级,到clientId,hidden,取clientId的值
              //#有点像转译符,让disabled原样输出
              "#disabled": "clients.@(3,clientId)"
            },
            "false": {
              "#enabled": "clients.@(3,clientId)"
            }
          }
        }
      }
    }
  }
]



json output

{
  "clients" : {
    "12" : "disabled",
    "35" : "enabled"
  }
}

基本情况简单转置 - Base case simple Transpose.

json input

{
  "data": {
    "clientId": "1234",
    "clientName": "Acme"
  }
}

json spec

[
  {
    "operation": "shift",
    "spec": {
      "data": {
        // @clientName取clientName的值Acme
        // @clientId取clientId的值1234
        "@clientName": "bookMap.@clientId"
        // 取clientName的值
        //第1级取cliendId的值 没有*所以从data里面开始clientName所以是1
        // "clientName": "bookMap.@(1,clientId)"
      }
    }
  }
]

json output

{
  "bookMap" : {
    "1234" : "Acme"
  }
}

复/嵌套转置 - Complex / nested Transpose.

json input

{
  "clientsActive": true,
  "clients": {
    "Acme": {
      "clientId": "Acme",
      "index": 1
    },
    "Axe": {
      "clientId": "AXE",
      "index": 0
    }
  },
  "data": {
    "bookId": null,
    "bookName": "Enchiridion"
  }
}

json spec

[
  {//先放一下,不好理解
    "operation": "shift",
    "spec": {
      "clientsActive": {
        "true": {
          "@(2,clients)": {
            // Test the ability to continue to match after doing a Transpose
            "*": {
              "clientId": "clientIds[@(1,index)]"
            }
          },
          // Verify that it something does not exist, it does not output a null
          "@(2,pants)": "pants"
        },
        "data": {
          // Verify the ability for Transpose to lookup and use a "valid" null, aka one that was in the input data
          "@bookId": "books.@bookName"
        }
      }
    }
  }
]

json output

{
  "clientIds" : [ "AXE", "Acme" ]
}

转译 - Escaping Shiftr special chars.

json input

{
  "comment" : "pulled from http://json-ld.org/playground/ example recipe.  Also, Mojitos are good.",

  "@context": {
    "name": "http://rdf.data-vocabulary.org/#name",
    "ingredient": "http://rdf.data-vocabulary.org/#ingredients",
    "yield": "http://rdf.data-vocabulary.org/#yield",
    "instructions": "http://rdf.data-vocabulary.org/#instructions",
    "step": {
      "@id": "http://rdf.data-vocabulary.org/#step",
      "@type": "xsd:integer"
    },
    "description": "http://rdf.data-vocabulary.org/#description",
    "xsd": "http://www.w3.org/2001/XMLSchema#"
  },
  "name": "Mojito",
  "ingredient": [
    "12 fresh mint leaves",
    "1/2 lime, juiced with pulp",
    "1 tablespoons white sugar",
    "1 cup ice cubes",
    "2 fluid ounces white rum",
    "1/2 cup club soda"
  ],
  "yield": "1 cocktail",
  "instructions": [
    {
      "step": 1,
      "description": "Crush lime juice, mint and sugar together in glass."
    },
    {
      "step": 2,
      "description": "Fill glass to top with ice cubes."
    },
    {
      "step": 3,
      "description": "Pour white rum over ice."
    },
    {
      "step": 4,
      "description": "Fill the rest of glass with club soda, stir."
    },
    {
      "step": 5,
      "description": "Garnish with a lime wedge."
    }
  ]
}

json spec

[
  {
    "operation": "shift",
    "spec": {
      //  因为 Java 所以使用//转译
      // 这些都要转译 . @ $ & \ [  ]
      "\\@context": {
        //内层几种取值的方法
        "name": "&1.Name",
        "ingredient": "&1.Inputs",
        "yield": "\\@context.Makes",
        // pass the rest thru
        //内层原样输出
        "*": "&1.&"
      },
      //三个字段重命名
      "name": "Name",
      "ingredient": "Inputs",
      "yield": "Makes",
      //剩余的原样输出
      "*": "&"
    }
  }
]

json output

{
  "comment" : "pulled from http://json-ld.org/playground/ example recipe.  Also, Mojitos are good.",
  "@context" : {
    "Name" : "http://rdf.data-vocabulary.org/#name",
    "Inputs" : "http://rdf.data-vocabulary.org/#ingredients",
    "Makes" : "http://rdf.data-vocabulary.org/#yield",
    "instructions" : "http://rdf.data-vocabulary.org/#instructions",
    "step" : {
      "@id" : "http://rdf.data-vocabulary.org/#step",
      "@type" : "xsd:integer"
    },
    "description" : "http://rdf.data-vocabulary.org/#description",
    "xsd" : "http://www.w3.org/2001/XMLSchema#"
  },
  "Name" : "Mojito",
  "Inputs" : [ "12 fresh mint leaves", "1/2 lime, juiced with pulp", "1 tablespoons white sugar", "1 cup ice cubes", "2 fluid ounces white rum", "1/2 cup club soda" ],
  "Makes" : "1 cocktail",
  "instructions" : [ {
    "step" : 1,
    "description" : "Crush lime juice, mint and sugar together in glass."
  }, {
    "step" : 2,
    "description" : "Fill glass to top with ice cubes."
  }, {
    "step" : 3,
    "description" : "Pour white rum over ice."
  }, {
    "step" : 4,
    "description" : "Fill the rest of glass with club soda, stir."
  }, {
    "step" : 5,
    "description" : "Garnish with a lime wedge."
  } ]
}

转置数组中的数据 - Transpose data in an Array.

json input

{
  "restaurantId": "ZZ4ORJDY3E",
  "chainId": "RLR932KI",
  "orderItems": [
    {
      "itemName": "Small Barqs",
      "quantity": 2
    },
    {
      "itemName": "Mozzz",
      "quantity": 1
    }
  ]
}

json spec

[
  {
    "operation": "shift",
    "spec": {
      "chainId": "retailer_id",
      "restaurantId": "store_id",
      "orderItems": {
      //遍历数组
        "*": {
          // value=quantity的值  1,2
          // basket_item[]数组输出
          // 数组key=itemName
          "quantity": "basket_item.[].@(1,itemName)"
        }
      }
    }
  }
]


json output

{
  "retailer_id" : "RLR932KI",
  "store_id" : "ZZ4ORJDY3E",
  "basket_item" : [ {
    "Small Barqs" : 2
  }, {
    "Mozzz" : 1
  } ]
}

根据数组中某个属性重建数组 - Bucket data from an Array, based on a leaf level value.

json input

{
  "entities": [
    {
      "type": "alpha",
      "data": "foo"
    },
    {
      "type": "beta",
      "data": "bar"
    },
    {
      "type": "alpha",
      "data": "zoo"
    }
  ]
}

json spec

[
  {
    "operation": "shift",
    "spec": {
      "entities": {
        //根据type的值重建数组
        "*": "@type[]"
      }
    }
  }
]

json output

{
  "alpha" : [ {
    "type" : "alpha",
    "data" : "foo"
  }, {
    "type" : "alpha",
    "data" : "zoo"
  } ],
  "beta" : [ {
    "type" : "beta",
    "data" : "bar"
  } ]
}

取一部分数据 - Filter data from an Array, based on a leaf level value.

json input

{
  "books": [
    {
      "title": "foo",
      "availability": [
        "online"
      ]
    },
    {
      "title": "bar",
      "availability": [
        "online",
        "paperback"
      ]
    },
    {
      "title": "baz",
      "availability": [
        "paperback"
      ]
    }
  ]
}

json spec

[
  {
    "operation": "shift",
    "spec": {
      "books": {
        "*": {
          "availability": {
            "*": {
              // if the value in the array is "paperback"
              // grab the whole "book object" and write it out to
              // a PaperBooks array.
              // The "@3" means go up the tree 4 levels and grab what is there
              // 4 levels up cause "real" programmers count from 0  ;)
              //只取有paperback的数据
              //数据取@3的数据books.availability.*
              "paperback": {
                "@3": "PaperBooks[]"
              }
            }
          }
        }
      }
    }
  }
]

json output

{
  "PaperBooks" : [ {
    "title" : "bar",
    "availability" : [ "online", "paperback" ]
  }, {
    "title" : "baz",
    "availability" : [ "paperback" ]
  } ]
}