条令ODM(mongo)-如果不存在,则追加嵌入文档



存在一个mongo文档,它链接了用户和汽车。它包含以下字段:

  • 用户.userId
  • 用户.汽车[]
  • 用户已更新
  • 用户创建

User.cars是嵌入文档的数组。如果不包含id为$carId的汽车,则需要编写一个查询,以便仅在此字段中插入一辆汽车

以下查询将每次为$userId和$carId创建一个新记录。它应该做的是要么不插入新记录,要么更新driven的值。

    $qb
        ->findAndUpdate()
        ->upsert(true)
        ->field('userId')->equals($userId)
        ->field('cars.id')->notEqual($carId)
        ->field('cars')->addToSet([
                'id' => $carId,
                'driven' => new DateTime(),
        ])
        ->field('updated')->set(new DateTime())
        ->field('created')->setOnInsert(new DateTime())
        ->limit(1)
    ;
    return $qb->getQuery()->execute();

从查询中删除notEqual($carId)将始终将记录插入User.cars,这也是不希望的。

最终的结果应该是User.cars只为每个carId包含一条记录。

如果以后不需要搜索cars的数组,可以将其存储为对象,并使用$carId作为关键字:

$qb
    ->findAndUpdate()
    ->upsert(true)
    ->field('userId')->equals($userId)
    ->field("cars.$carId")->set([
            'id' => $carId,
            'driven' => new DateTime(),
    ])
    ->field('updated')->set(new DateTime())
    ->field('created')->setOnInsert(new DateTime())
    ->limit(1)
;
return $qb->getQuery()->execute();

如果cars在文档中映射为EmbedMany,您可能需要将集合的策略更改为setatomicSet(我建议后者),否则ODM将在每次保存数组时重新索引数组。

同样,此解决方案也有其缺点,根据您希望如何使用数据,这些缺点可能会被认为是严重的,但它解决了有问题的问题。

顺便说一下,->limit(1)是多余的,因为->findAndUpdate()正在使查询运行findAndModify命令,该命令本质上对单个文档进行操作。

相关内容

  • 没有找到相关文章

最新更新