问题描述
使用自带的mongoimport.exe导入test.csv文件(测试内容如下):
name,passtest1,ztj'ile0test2,'audreyhepburn'test3,Xiaoya”””oge521test4,''520xiangbin
问题:导入后使用find({name:/^test/})查询,发现pass字段全部显示错误(和csv中原值完全不同,显示为空值或者只有一半文本等)——请问MongoDB如何正确插入带双引号的文本记录??
无论是逐条insert还是批量import都无法插入带双引号的记录,即使使用“”转义也不行,求大神!
问题解答
回答1:根据 CSV 的标准:
file = [header CRLF] record *(CRLF record) [CRLF] header = name *(COMMA name) record = field *(COMMA field) name = field field = (escaped / non-escaped) escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE non-escaped = *TEXTDATA COMMA = %x2C CR = %x0D DQUOTE = %x22 LF = %x0A CRLF = CR LF TEXTDATA = %x20-21 / %x23-2B / %x2D-7E
你举的例子中,test1 和 test4 都是不合法的,虽然我没有确认 MongoDB 是严格按照 RFC 4180 的标准来解析 CSV 的,但你的文件格式肯定是有很大问题。
因此还是建议先用工具把你的 CSV 文件标准化之后再导入数据库,不知道你的数据量有多大,但这只是简单的文本处理,耗时应该是可以接受的。
下面是一个方案,虽然不完美,但应该适用大多情况:
# 除了首行之外,对于每一行:for line in file[1 ...] # 将第一个逗号前的部分作为 name, 逗号后的作为 pass [1:name, 2:pass] = line.match /^([^,])+,(.*)/ # 如果存在 name 和 pass if name and pass # 如果在忽略首尾空格的情况下 pass 不是以双引号开头和结尾的,或者 pass 中间存在单个双引号就进行重新转义 unless pass.trim().match(/^'.*'$/) and !pass.match(/[^']'[^']/) # 重复双引号 pass = pass.replace /'/, ’''’ # 在前后加上双引号 pass = ’'’ + pass + ’'’ console.log [name, pass].join ’,’
https://tools.ietf.org/html/rfc4180