Perl& MongoDB二进制数据

时间:2012-06-20 08:41:49

标签: perl mongodb

来自MongoDB手册:

  

默认情况下,所有数据库字符串都是UTF8。要保存图像,二进制文件,   和其他非UTF8数据一样,可以将字符串作为引用传递给   数据库中。

我提取网页并希望存储内容以供日后处理。

  • 我不能依赖meta-charset,因为很多页面都有utf8内容但错误地声明iso-8859-1或类似
  • 所以无法使用Encode(不知道原始字符集)
  • 因此,我希望简单地存储内容as flow of bytes(二进制数据)以供日后处理

我的代码片段:

sub save {
    my ($self, $ok, $url, $fetchtime, $request ) = @_;

    my $rawhead = $request->headers_as_string;
    my $rawbody = $request->content;

    $self->db->content->insert(
        { "url" => $url, "rhead" => \$rawhead, "rbody" => \$rawbody } ) #using references here
      if $ok;

    $self->db->links->update(
        { "url" => $url },
        {
            '$set' => {
                'status'       => $request->code,
                'valid'        => $ok,
                'last_checked' => time(),
                'fetchtime'    => $fetchtime,
            }
        }
    );
}

但是得到错误:

  

子程序条目中的宽字符   /opt/local/lib/perl5/site_perl/5.14.2/darwin-multi-2level/MongoDB/Collection.pm   第296行。

这是我存储数据的唯一地方。

问题:在MondoDB中存储二进制数据的唯一方法是对它们进行编码,例如:用base64?

2 个答案:

答案 0 :(得分:4)

这看起来像是关于_utf8_旗帜的另一个悲伤故事......

我可能错了,但似乎HTTP :: Message的headers_as_stringcontent方法将字符串作为字符序列返回。但MongoDB驱动程序期望显式传递给它的字符串作为'二进制文件'是一个八位字节序列 - 因此警告剧。

一个相当丑陋的修复方法是在你的代码中删除$ rawhead和$ rawbody上的utf8标志(我不知道它应该由MongoDB驱动程序本身完成吗?),通过类似这样的东西。

_utf8_off $rawhead; 
_utf8_off $rawbody; # ugh

替代方法是使用encode('utf8', $rawhead) - 但是在从DB中提取值时应该使用decode,我怀疑它不是更丑陋。

答案 1 :(得分:0)

您的数据是字符,而不是八位字节。你的假设似乎是你只是把事情作为八位字节传递,但你必须先通过解码传入的文本数据以某种方式违反了这个假设,甚至可能没有你注意到。

所以简单地不解码,数据保持八位字节,存储到数据库中不会失败。