【问题标题】:Mongo lookup to return local even when foreign not matched即使外国不匹配,Mongo 查找也会返回本地
【发布时间】:2021-02-17 01:00:17
【问题描述】:

假设我有User 集合,一个用户可以有很多Books

我想查询User,然后查找以获取Books 数据,具有特定的userIdbookId,但是当该用户没有Books 时,仍然返回带有空书的用户数据或为空。

Mongo:3.4

我试过了。

$this->mongo->selectCollection('users')->aggregate([
    ['$match' => ['userId' => $userId]],
    [
        '$lookup' => [
            'from' => 'books',
            'localField' => 'userId',
            'foreignField' => 'userId',
            'as' => 'books'
        ]
    ],
    ['$unwind' => [
        'path' => '$books',
    ]],
    ['$match' => ['books.bookId' => $bookId]]
]);

问题: 上面的代码,当书不匹配时会返回空结果。我仍然想获取用户数据。

我期望的示例结果是:

找到书时

user : {
    userId: 1
    name: xxx,
    books: {
        name: Book name
        userId: 1
    }
}

找不到书时

user : {
    userId: 1,
    name: xxx,
    books: null or whatever
}

【问题讨论】:

  • 在最后一场比赛中,您将 bookId 与 userId 进行比较,这对我来说毫无意义。移除舞台,您将拥有所有用户,即使是没有书籍的用户。
  • @AlexBlex 抱歉,在创建简单示例时打错了['books.bookId' => $bookId]
  • 你需要在这里使用$filter聚合来匹配你将通过的bookId。或者您可以将$lookup 3.6 语法与管道一起使用。
  • 删除$unwind$match,在$lookup之后使用这个阶段['$addFields' => [ 'books' => [ '$filter' => [ 'input' => '$books', 'as' => 'book', 'cond' => [ '$eq' => ['$book.userId', bookId]] ] ] ]]
  • @AnthonyWinzlet 成功了,谢谢。你有一个小错字,应该是['$$book.userId, double $。请作为答案发布,以便我接受。

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

您需要使用$filter 聚合来过滤books 数组。

$this->mongo->selectCollection('users')->aggregate([
  [ '$match' => ['userId' => $userId]],
  [ '$lookup' => [
    'from' => 'books',
    'localField' => 'userId',
    'foreignField' => 'userId',
    'as' => 'books'
  ]],
  [ '$addFields' => [
    'books' => [
      '$filter' => [
        'input' => '$books',
        'as' => 'book',
        'cond' => [ '$eq' => ['$$book.userId', bookId]]
      ]
    ]
  ]]
])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多