MongoError:当存储由xml2js模块生成的JSON对象时,key $不能以'$'开头

大家,

MongoDB db.version() is 3.0.5 mongodb package.json shows 2.0.42 version xml2js package.json shows 0.4.9 version 

我已经search了这个错误,并通读了所有现存的问题,而且没有一个符合我的情况(无论是jira问题还是gogle团队讨论等)。 这可能与mongodb本地驱动程序(或MongoDB服务器版本),xml2js或其他。

我做了大量的testing,并find了解决问题的方法,但是,我很想知道问题是什么。

我有一个应用程序,执行以下操作:

  1. 将XForm(survey.xml)上传到ExpressJS
  2. 使用xml2js库将XML转换为JSON对象(示例如下所示)
  3. 迭代2中创build的JSON对象,并删除不必要的字段(代码段代码如下所示)
  4. 使用mongodb本地驱动将3中修改的JSON对象推送到MongoDB

第4步失败,出现错误(在问题的标题中显示)。

  1. 有2个JSON对象,其中一个是调查表单,包含$ keys,但在将文档插入到mongodb之前,使用以下代码删除$键

     (function traverse(o) { for (var i in o) { if (o[i] !== null && typeof(o[i])=="object") { //going on step down in the object tree!! if(o[i].$) { var ref = ""; if(o[i].$.ref) { ref = o[i].$.ref; } else if (o[i].$.nodeset) { ref = o[i].$.nodeset; } o[i].ref = ref; o[i].$ = undefined; var chunks = ref.split('/'); o[i]['name'] = chunks[chunks.length - 1]; } traverse(o[i]); } } })(body); 
  2. 在将控制台添加到MongoDB之前,我将控制台logging到上面的输出中,并且console.log显示没有使用$的密钥符号。

  3. 假设步骤2实际上是因为键中的$失败而失败的,我还有另外一个JSON,它是调查的响应,不包含任何$,但是也失败了,同样的错误(MongoError:key $ must不以'$'开始)。

     db.collection('submissions').insert(jsonObject, function(err, result) { if(err) console.log('error is : ' + err); console.log('insertion result : ' + JSON.stringify(result)); }); 

以下是XML表单提交

  <?xml version='1.0' ?> <ppe id="ppe_checklist_new"> <starting_repeat> <location>dark_room</location> <ppe_dark>safety_glasses</ppe_dark> <xyz_group> <condition>condition_missing</condition> <test_condition>b</test_condition> </xyz_group> </starting_repeat> <starting_repeat> <location>nitrogen_store</location> <ppe_nitrogen>leather_gloves_s</ppe_nitrogen> <xyz_group> <condition>condition_replacing</condition> <test_condition /> </xyz_group> </starting_repeat> <starting_repeat> <location>nitrogen_store</location> <ppe_nitrogen>blue_gloves_m</ppe_nitrogen> <xyz_group> <condition /> <test_condition>b</test_condition> </xyz_group> </starting_repeat> <starting_repeat> <location>cold_room_first</location> <ppe_cold>hearing_muff_1</ppe_cold> <xyz_group> <condition>condition_ok</condition> <test_condition>f</test_condition> </xyz_group> </starting_repeat> <sample_group> <date>2015-08-24</date> <random_number>55</random_number> </sample_group> <another_group> <another_repeat> <sample_text>Sample text 1</sample_text> <image /> </another_repeat> <another_repeat> <sample_text>Sample text 2</sample_text> <image /> </another_repeat> </another_group> <form_done>OK</form_done> <survey_start>2015-08-24T16:55:23.185+01</survey_start> <survey_end>2015-08-24T16:57:24.460+01</survey_end> <survey_day>2015-08-24</survey_day> <survey_device>353490061313389</survey_device> <meta> <instanceID>uuid:2aba0eff-5350-47e3-9e9c-9606d2c9e7d6</instanceID> </meta> </ppe> 

我将以上configuration提供给xml2js模块:

 function parseXMLToJS(filename, path, callback) { var parser = new xml2js.Parser({explicitArray:false}); var fileURL = path + filename; var data = fs.readFile(fileURL, function(err, data) { if(err) { logger.error('Error reading submission file. Error %', err); } else { parser.parseString(data, function (err, result) { if(err) { logger.error('Error parsing XML to JS. Error : %', err); callback({parsed:false, result:result}); } else { callback({parsed:true, result:result}); } }); } }); } 

并且该模块生成一个JSON对象,如下所示:

 { "ppe": { "starting_repeat": [ { "location": "dark_room", "ppe_dark": "safety_glasses", "xyz_group": { "condition": "condition_missing", "test_condition": "b" } }, { "location": "nitrogen_store", "ppe_nitrogen": "leather_gloves_s", "xyz_group": { "condition": "condition_replacing", "test_condition": "" } }, { "location": "nitrogen_store", "ppe_nitrogen": "blue_gloves_m", "xyz_group": { "condition": "", "test_condition": "b" } }, { "location": "cold_room_first", "ppe_cold": "hearing_muff_1", "xyz_group": { "condition": "condition_ok", "test_condition": "f" } } ], "sample_group": { "date": "2015-08-24", "random_number": "55" }, "another_group": { "another_repeat": [ { "sample_text": "Sample text 1", "image": "" }, { "sample_text": "Sample text 2", "image": "" } ] }, "form_done": "OK", "survey_start": "2015-08-24T16:55:23.185+01", "survey_end": "2015-08-24T16:57:24.460+01", "survey_day": "2015-08-24", "survey_device": "353490061313389", "id": "ppe_checklist_new", "uuid": "2aba0eff-5350-47e3-9e9c-9606d2c9e7d6" } } 

我试图检查我插入到MongoDB的数据是否是对象,事实certificate它是。

 typeof(result.result) 
  1. 尝试通过Mongo Shell从xml2js插入生成的JSON对象,它工作。
  2. 试图在我的JavaScript代码中创build一个JS对象与由xml2js生成的JSON相同的内容,并通过mongodb本地驱动程序插入到MongoDB工作(即使我比较两个JSON和他们是完全一样的)。

总之,我可以说mongodb本地驱动程序不喜欢由xml2js模块生成的JSON对象,为什么我不知道? 我等不及要知道。 我尝试了以下解决方法

  1. 使用xml2js转换XML 2 JSON
  2. 将xml2js中返回的JSON对象string化(x = JSON.stringify(obj);)
  3. parsingstring化的JSON对象(parsedX = JSON.parse(x);)
  4. 通过mongodb本地驱动器插入parsing的值到MongoDB,它的工作。

不pipe这个问题是什么,上面的错误信息是有点误导或可能不适合这个问题,正在造成它。 我找不到一个方法来获得更详细的错误(也许有一种方式,mongodb提供更多的解释,很想知道)。

感谢您的时间和耐心。

traverse函数的以下行只是将$字段设置为undefined的值,而不实际删除它。

 o[i].$ = undefined; 

更改该行以使用delete来删除它:

 delete o[i].$; 

使用JSON.stringifyJSON.parse解决方法是JSON.stringify ,因为undefined值无法用JSON表示,因此JSON.stringify调用会删除具有该值的字段。