【问题标题】:MongoDB $lookup with _id as a foreignField in PHPMongoDB $lookup 与 _id 作为 PHP 中的 foreignField
【发布时间】:2016-06-01 19:25:20
【问题描述】:

我用这个在桌子上敲打我的头太久了......

我有两个 MongoDB 集合:“聊天室”和“用户”。 "chatroom" 集合中的 "user_id" 键指向 "users" 集合中的特定单个用户。

我正在尝试使用 $lookup 聚合查询与用户一起获取聊天室,我目前拥有的是这个:

$this->mongo->chatroom->aggregate(
    array('$lookup' => array(
        'from' => 'users',
        'localField' => 'user_id',
        'foreignField' => '_id',
        'as' => 'user'
    ))
);

但是,这会在集合中返回一个空的“用户”字段。奇怪的是,如果我尝试用设置为 _id.$id 值的自定义“uid”替换“_id”,它会按预期工作:

$this->mongo->chatroom->aggregate(
    array('$lookup' => array(
        'from' => 'users',
        'localField' => 'user_id',
        'foreignField' => 'uid', // uid = _id.$id
        'as' => 'user'
    ))
);

我发现问题是“_id”是 ObjectId 而“user_id”是字符串。但是我不知道如何很好地处理这个问题......

【问题讨论】:

    标签: php mongodb


    【解决方案1】:

    为了回答我自己的问题,我通过将“user_id”设置为“MongoId”类的实例而不是纯字符串来解决该问题。基本上,我将“user_id”存储为:

    $mongoObject["user_id"] = new MongoId($this->user_id);
    

    另一种解决方案可能是用值等于“_id.$id”的“uid”字段装饰对象。

    【讨论】:

    • 实际上根本不是"..解决问题"(原文如此),而是“纠正”问题。就像发出 any 查询一样,数据必须是相同的“类型”才能匹配。所以"localField""foreignField" 必须都具有相同的 BSON 类型,否则后续的“查询”会失败。就像您尝试使用作为字符串而不是重新转换的 _id 来查询您的 users 集合一样,那么该查询将不会返回任何结果。没有区别,而且是设计使然。
    • 是的,我明白这一点并同意这是一个正确的行为 - 只是有点困惑,因为我找不到任何方法在聚合查询中进行转换,并且可视化工具没有告诉我类型(只是将值显示为字符串)。
    • 你不能在聚合中“重新转换”类型(有一些有趣的例外,但这是一般规则)或者至少对于ObjectId 来说不是。正确的做法是将两种类型更改为相同,以便它们确实“匹配”。还要始终使用mongo shell 来检查数据。它可能缺乏“花里胡哨”,但它是“保证”向您展示正确类型的一件事。它是官方产品,因此应该可以预期。接受你自己的答案。这是正确的方法。
    猜你喜欢
    • 1970-01-01
    • 2016-10-08
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 2019-06-29
    • 2015-01-02
    • 2018-11-27
    • 1970-01-01
    相关资源
    最近更新 更多