2016-10-06 22 views
4

我有一個data.table像這樣的:如何刪除」時如何寫R字對象到JSON

test <- data.table(city = c("Berlin", "Berlin", "Berlin", "Amsterdam", "Amsterdam"), 
        key1 = c("A", "A", "A", "B", "B"), 
        value1 = c(1, 2, 3, 4, 5), 
        value2 = c(0.1, 0.2, 0.3, 0.4, 0.5), 
        kpi = c(10, 15, 20, 25, 30)) 

我想將這些數據上傳到Elasticsearch,但具體的結構:

library(RJSONIO) 
res <-test[, .(factors = toJSON(.SD)), 
      by = .(city, key1), 
      .SDcols = c("value1", "kpi")] 

此代碼創建,在列factors,不同JSONs因爲我想擺脫\n序列,該庫介紹,我可以在分配替換這些字符串:

res <-test[, .(factors = gsub("\n", "", toJSON(.SD))), 
     by = .(city, key1), 
     .SDcols = c("value1", "kpi")] 

問題出現在我想上傳這個對象到Elasticsearch(我正在使用elastic包)。由於R用反斜槓字符串內逃脫雙引號,當我寫使用對象:

docs_bulk(res, "index") 

它在使用內toJSONvalue1kpi)創建的字符串字段中寫入\"代替"。寫入對象時到一個文件這也可以檢查:

write(toJSON(res), "~/output.json") 

{ 
"city": [ "Berlin", "Amsterdam" ], 
"key1": [ "A", "B" ], 
"factors": [ "{ \"value1\": [1, 2, 3 ],\"kpi\": [10, 15, 20 ] }", "{ \"value1\": [ 4, 5 ],\"kpi\": [25, 30 ] }" ] 
} 

由於value1kpi開始的姓名和與\"結束,這些字段不是由Elasticsearch解析爲分離陣列。我想有是這樣的:

{ 
"city": [ "Berlin", "Amsterdam" ], 
"key1": [ "A", "B" ], 
"factors": [ { "value1": [1, 2, 3 ],"kpi": [10, 15, 20 ] }, { "value1": [4, 5 ],"kpi": [25, 30 ] } ] 
} 

我已經試過regexs gsub幾種不同的組合,但我無法阻止[R從寫反斜槓。我最後的選擇是將對象寫入文件並使用sed手動解析,但我認爲應該有一個更簡單的方法。任何幫助將不勝感激。

+0

'elastic'維護者這裏:爲我的作品。我在'elastic'' v0.7.6.9500',和Elasticsearch'v2.3.5' - 你正在運行什麼版本? – sckott

+0

Hi @sckott我使用Elasticsearch 2.3.3和'elastic' v0.7.6。對我來說,它也將文件加載到Elasticsearch中沒有錯誤,但問題是字段'factors'是:''{\「value1 \」:[1,2,3],\「kpi \」:[10 ,15,20]}「',所以它被解析爲一個完整的字符串,而不是具有兩個數組的對象。也許我在這裏錯過了一些東西? –

+0

當我編寫「未正確解析」時,我並不是說它會生成一個錯誤,但由於反斜槓是由R引入的,因此它不會像我期望的那樣被解析。對此感到抱歉。 –

回答

3

好吧,我認爲這應該做到這一點。可能是更少的代碼進入決賽res對象批量加載,但無論如何

library(elastic) 
library(data.table) 
library(jsonlite) 

test <- data.table(city = c("Berlin", "Berlin", "Berlin", "Amsterdam", "Amsterdam"), 
        key1 = c("A", "A", "A", "B", "B"), 
        value1 = c(1, 2, 3, 4, 5), 
        value2 = c(0.1, 0.2, 0.3, 0.4, 0.5), 
        kpi = c(10, 15, 20, 25, 30)) 

res <- test[, .(factors = jsonlite::toJSON(.SD, dataframe = "columns")), 
      by = .(city, key1), 
      .SDcols = c("value1", "kpi")] 

res <- lapply(apply(res, 1, as.list), function(z) { 
    tt <- z[!names(z) %in% "factors"] 
    tt$factors <- fromJSON(z$factors) 
    tt 
}) 

docs_bulk(res, "mycoolindex") 

curl 'http://localhost:9200/mycoolindex/_search?size=1' | jq . 
#> { 
#> "took": 13, 
#> "timed_out": false, 
#> "_shards": { 
#>  "total": 5, 
#>  "successful": 5, 
#>  "failed": 0 
#> }, 
#> "hits": { 
#>  "total": 2, 
#>  "max_score": 1, 
#>  "hits": [ 
#>  { 
#>   "_index": "mycoolindex", 
#>   "_type": "mycoolindex", 
#>   "_id": "AVeay0KnlE0U0vVWYXkb", 
#>   "_score": 1, 
#>   "_source": { 
#>   "city": [ 
#>    "Amsterdam" 
#>   ], 
#>   "key1": [ 
#>    "B" 
#>   ], 
#>   "factors": { 
#>    "value1": [ 
#>    4, 
#>    5 
#>    ], 
#>    "kpi": [ 
#>    25, 
#>    30 
#>    ] 
#>   } 
#>   } 
#>  } 
#>  ] 
#> } 
#> } 
+0

非常感謝您的幫助。 –

+0

@JaimeCaffarel:我有一個相同的問題,但我在這裏沒有找到答案,所以非常清楚。你有沒有得到一個簡單的解決方案來從作爲字符輸出寫入的toJSON中移除\? sckott給出的解決方案看起來很龐大,並不確定它是否解決了\或其他問題。在提出新的SO問題之前,我會等待您的意見。 –

+0

@sanjmeh不,我沒有嘗試更簡單的實現。 –