繁体   English   中英

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

[英]Having problems parsing strings into objects in javascript and JSON

我正在查询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: 'select test, score from test_by_score where commit = ?'

因此,索引0从table test_by_score获取列“test”。 我们可以确认它的一个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来解释问题以及为解决它而做的事情(以及为解决这个bug而进行的任何讨论)。

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

gitissue还为人们提供参考,以便了解如何在原始回购中解决问题。

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

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

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

可以解决问题。

还要考虑将BLOB更改为VARCHAR,如下所述: 将序列化java对象存储为cassandra作为JSON的思考。 捕获量是多少?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM