首页 > 解决方案 > MongoDB/Perl:find_one 在无关代码后不返回数据

问题描述

mongodb是v4.0.5

Perl 是 5.26.3

MongoDB Perl 驱动程序是 2.0.3

这个 Data::Dumper 输出显示了是什么让我发疯

INFO - $VAR1 = [
  '275369249826930689 1',
  {
    'conf' => {
      'param' => 'argument'
    },
    'id' => '275369249826930689',
    'lastmsg' => '604195211232139552',
    '_id' => bless( {
      'oid' => ']:\',&�h�GeR'
    }, 'BSON::OID' )
  }
];

352832438449209345 275369249826930689
INFO - $VAR1 = [
  '275369249826930689 2'
];

第二个 INFO - $VAR1 应该显示与第一个相同的内容。这是原始代码,我已经(见下文)分解以找到罪魁祸首。

    ddump(["$userid 1",
        $c_identities->find_one({
            channel => 'chan1',
            id      => $userid,
        })
    ]);
    my @filtered = reverse      
                   grep { $_->{author}->{id} == $userid } @{$answers};

    ddump(["$userid 2",
        $c_identities->find_one({
            channel => 'chan1',
            id      => $userid,
        })
    ]);

ddump 只是 Data::Dumper 的包装器。如果我删除“my @filtered”行,第二个 find 将再次返回预期结果(MongoDB 文档)。$answers 只是来自某些 API 的哈希列表引用 - 没有对象 - 与 MongoDB 完全无关。

所以我打破了“反向grep”代码,看看罪魁祸首在哪里。说的是你在上面的倾倒者之间看到的两个数字。这是我能做的,从第二个 find_one 得到答案:

    for my $answer (@{$answers}) {
        say $answer->{author}->{id}, ' ', $userid;
        push @filtered, $answer;
    }

只要我这样做,第二个 find_one 就会提供结果。但是,如果我这样做:

    for my $answer (@{$answers}) {
        say $answer->{author}->{id}, ' ', $userid;
        if ($answer->{author}->{id} == $userid) {
        }
        push @filtered, $answer;
    }

我从上面得到输出(第二个转储程序没有从 find_one 产生任何返回。这太疯狂了 - 包含数字 eq 的 if 子句导致第二个 find_one 失败!这也是预期代码中的 grep 主体。

这里发生了什么?这怎么可能对 MongoDB 方法产生任何影响?

标签: mongodbperl

解决方案


使用数字比较运算符==会计算值,但它可能太大而无法放入整数并变成浮点数。当序列化为 JSON 或类似格式时,它也可以变成一个整数并丢失双引号。使用eq而不是==保持值不变。


推荐阅读