在使用javascript和JSON将字符串解析为对象时遇到问题

时间:2014-05-03 05:03:23

标签: javascript json parsing cassandra

我正在查询Cassandra数据库,然后尝试将其中一个BLOB条目转换为javascript对象。

目前有一行获取我感兴趣的数据/ blob:

data[x][0]

当我在console.log上时用:

console.log("data[x][0]: ", data[x][0]);

输出结果为:

data[x][0]:  <Buffer 7b 22 70 72 65 66 69 78 22 3a 20 22 65 6e 77 69 6b 69 22 2c 20 22 74 69 74 6c 65 22 3a 20 22 22 41 67 68 6e 61 64 61 72 72 61 67 68 22 22 7d>

所以我总结了它的一些十六进制缓冲区对象(我以前见过),所以我尝试用toString()方法将它变成一个字符串然后在那之后我们可以解析它并使它成为一个javascript对象!

首先,我测试了toString()方法:

console.log("data[x][0].toString(): ", data[x][0].toString());

以下是输出:

data[x][0].toString():  {"prefix": "enwiki", "title": ""Aghnadarragh""}

哪个看起来很完美!这是我想要创造的对象! (虽然现在是一个字符串)

那么......为什么不用JSON解析大坝呢?它看起来像JSON ......

console.log( "JSON.string(data[x][0]): ", JSON.parse( data[x][0].toString() ) );

好吧,如果我这样做,我会收到JSON库抛出的错误:

events.js:72
        throw er; // Unhandled 'error' event
              ^
SyntaxError: Unexpected token A
    at Object.parse (native)
    at CassandraBackend.queryCB2 (/home/brandomiranda/Documents/6.S194/testreduce/CassandraBackend.js:831:70)
    at Object.callback (/home/brandomiranda/Documents/6.S194/testreduce/node_modules/node-cassandra-cql/index.js:248:16)
    at Connection.handleFrame (/home/brandomiranda/Documents/6.S194/testreduce/node_modules/node-cassandra-cql/lib/connection.js:244:15)
    at FrameParser.<anonymous> (/home/brandomiranda/Documents/6.S194/testreduce/node_modules/node-cassandra-cql/lib/connection.js:45:12)
    at FrameParser.EventEmitter.emit (events.js:92:17)
    at emitReadable_ (_stream_readable.js:408:10)
    at emitReadable (_stream_readable.js:404:5)
    at readableAddChunk (_stream_readable.js:165:9)
    at FrameParser.Readable.push (_stream_readable.js:127:10)

从错误消息中,我猜我给它的字符串形成一些无法正确解析的令牌(可能因为它不遵守JSON语法将是我的猜测)。

但是,如果它不是JSON,那么它是什么?它也很难知道它是什么语法,因为我不知道原始物体是什么类型的物体:

这样做的:

console.log(typeof data[x][0]);

不会产生有用的信息:

object

如何将该字符串转换为Javascript对象?


注意:此项目正在使用Cassandra 2.0.5

这来自一个开源项目,生成此代码的确切行可以在以下位置找到:

https://github.com/gwicke/testreduce/blob/master/CassandraBackend.js#L830

仔细研究整个开源我们可以确认data[x][0]确实来自Cassandra并且它是一个blob。

data[x]索引Cassandra查询的特定行。 data[x][0]为列编制索引。在顶部,我们可以看到从db获取的行由query:

指定
query: 'select test, score from test_by_score where commit = ?'

因此,索引0得到列&#34; test&#34;来自table test_by_score。我们可以确认它是一个blob:

    CREATE TABLE IF NOT EXISTS test_by_score (
        commit blob, 
        delta int, 
        score int, 
        test blob, 
    PRIMARY KEY(commit, delta, test) );

所以我的推论是,Cassandra给出了错误并且没有生成正确的JSON对象或者...在测试时最初插入的内容没有正确插入JSON对象...可能是哪一个?让我们再探讨一下!


在开源代码库

上为这个bug做了一个gitissue

作为参考,我还在github上做了一个gitissue来解释问题以及为解决这个问题所做的事情(以及为解决这个问题而进行的任何讨论。

https://github.com/gwicke/testreduce/issues/43

gitissue还为人们提供了一个参考,让他们知道如何在原始回购中解决问题。

1 个答案:

答案 0 :(得分:1)

我认为问题出在框架中:因为它似乎使用双引号表示法将值插入到Cassandra中。在JSON中,首选的是单引号表示法。

您有两种方法可以解决此问题:要么为即将到来的upsert使用单引号(旧数据必须截断,因为它不可读)或者您通过解决方法解决问题:来自'Aadit M Shah'的评论删除内部双引号可能会起作用 - 但您的应用程序可能需要它们。所以我认为问题需要一些更复杂的RegExp,因为你只想替换内部双引号。

JSON.parse(data[x][0].toString().replace(/\"\"\(.*)\"\"/g, /\"\'$1\'\"/)

可以解决问题。

还可以考虑将BLOB更改为VARCHAR,如下所述: Thinking of storing serialized java objects into cassandra as JSON. What is the catch?