php - PHP MongoDB\Client updateOne 将新字段添加到现有文档数组
问题描述
我正在努力更新文档并将新元素(字段)添加到它的现有数组中,而不会丢失更新时的数组元素。
这是我的代码,它在集合中插入一个新文档(如果它尚不存在)(upsert):
$updateResult = $collection->findOneAndUpdate(
[
'recording-id' => $out['recording']->id
],
['$set' => [
'release' => [
'id' => $out['release']->id,
'title' => $out['release']->title,
'date' => $out['release']->date,
'country' => $out['release']->country
],
'artist' => [
'id' => $out['artist']->id,
'name' => $out['artist']->name,
],
'recording' => [
'id' => $out['recording']->id,
'title' => $out['recording']->title,
'score' => $out['recording']->score,
'length' => $out['recording']->length,
'release-count' => count($out['recording']->releases),
],
'release-group' => [
'id' => $out['release-group']['id'],
'title' => $out['release-group']['title'],
'first-release-date'=>$out['release-group']['first-release-date'],
'primary-type' => $out['release-group']['primary-type'],
'musicbrainz' => $out['release-group']['musicbrainz'],
'url-rels' => $out['release-group']['url-rels'],
'coverart' => $out['release-group']['coverart']
],
'execution' => [
'firstfind' => $out['execution']->time
]
]
],
['upsert' => true,
'projection' =>
[
'_id' => 0,
'release' => 1,
'artist' => 1,
'recording' => 1,
'release-group' => 1,
'execution' => 1
],
'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
]
);
所以现在我在集合中有一个现有的文档:
{
"_id" : ObjectId("5d1a6aaf5ecc8001ee858f6c"),
"recording-id" : "d0d439f9-5324-4728-8706-2da39adb89c5",
"artist" : {
"id" : "9d97b077-b28d-4ba8-a3d9-c71926e3b2b6",
"name" : "Gordon Lightfoot"
},
"recording" : {
"id" : "d0d439f9-5324-4728-8706-2da39adb89c5",
"title" : "Sundown",
"score" : 100,
"length" : 184000,
"release-count" : 2
},
"release" : {
"id" : "0c008d76-2bc9-44a3-854b-0a08cde89337",
"title" : "All Live",
"date" : "2012-04-24",
"country" : "CA"
},
"release-group" : {
"id" : "0a5d5f33-8e9d-4fa4-b622-a95e4218a3c4",
"title" : "All Live",
"first-release-date" : "2012-04-24",
"primary-type" : "Album",
"musicbrainz" : "https://musicbrainz.org/release-group/0a5d5f33-8e9d-4fa4-b622-a95e4218a3c4",
"url-rels" : "https://musicbrainz.org/ws/2/release-group/0a5d5f33-8e9d-4fa4-b622-a95e4218a3c4?inc=url-rels&fmt=json",
"coverart" : null
}
}
现在,我想更新此文档,并将新字段添加到数组中。新字段将添加到某些字段。这是执行此操作的代码:
$collection = (new MongoDB\Client)->stream->musicbrainz;
$updateResult = $collection->updateOne(
[
'recording-id' => $out['recording']['id']
],
['$addToSet' => [
'artist' => [
'wikiQiD' => $out['artist']['qid'],
'wiki-extract' => $out['artist']['wiki-extract'],
'wiki-pageid' => $out['artist']['pageid'],
],
'release-group' => [
'wikiQiD' => $out['release-group']['qid'],
'wiki-extract' => $out['release-group']['wiki-extract']
]
]
],
[
'upsert' => true,
'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
]
);
我注意到有“$addToSet”和“$push”命令,并且可以帮助了解这两个命令之间的区别。
如果要更新的文档中不存在该字段,则 $push 会添加具有该值的数组字段作为其元素。
$addToSet 运算符向数组添加一个值,除非该值已经存在,在这种情况下,$addToSet 对该数组不做任何事情。
我做了一些谷歌搜索,并阅读了 MongoDB/Client UpdateOne 函数,但似乎找不到将这些字段附加到现有数组的方法。
我得到的错误是:
Fatal error: Uncaught MongoDB\Driver\Exception\BulkWriteException: The field 'artist' must be an array but is of type object in document {_id: ObjectId('5d1a6aaf5ecc8001ee858f6c')} in ...
我知道以下内容:
- 它可能是我的文档,因为它不是致命错误所抱怨的正确数组。
- 这可能是我的“findOneAndUpdate”格式,而我没有正确地这样做。
- 可能两者都是,我从一开始就错了。
任何洞察力或建设性的批评都会受到赞赏,请不要火上浇油。
解决方案
这是我最终用来让它做我想做的事情的工作代码。
只需设置字段名称和值很简单,mongo 将更新找到的记录,并将其替换为发送给它的数组。无需推动或任何东西。
function firstFindMongoUpdate($out) {
$collection = (new MongoDB\Client)->stream->musicbrainz;
$updateResult = $collection->findOneAndUpdate(
[
'recording-id' => $out['recording']->id
],
['$set' => [
'query' => $out['query'],
'release' => [
'id' => $out['release']->id,
'title' => $out['release']->title,
'date' => $out['release']->date,
'country' => $out['release']->country,
'label' => $out['release']->label,
],
'artist' => [
'id' => $out['artist']->id,
'name' => $out['artist']->name,
'wiki' => $out['artist']->wiki,
],
'recording' => [
'id' => $out['recording']->id,
'title' => $out['recording']->title, // sometimes contains apostophe ie; Bill‘s Love (option ] key)
'score' => $out['recording']->score,
'length' => $out['recording']->length,
'release-count' => count($out['recording']->releases)
],
'release-group' => [
'id' => $out['release-group']['id'],
'title' => $out['release-group']['title'],
'first-release-date'=>$out['release-group']['first-release-date'],
'primary-type' => $out['release-group']['primary-type'],
'musicbrainz' => $out['release-group']['musicbrainz'],
'url-rels' => $out['release-group']['url-rels'],
'coverart' => $out['release-group']['coverart'],
'wiki' => $out['release-group']['wiki']
],
'execution' => [
'artistQuery' => $out['execution']->artistQuery,
'recordingQuery'=> $out['execution']->recordingQuery,
'time' => $out['execution']->time
]
]
],
['upsert' => true,
'projection' =>
[
'_id' => 1,
'query' => 1,
'release' => 1,
'artist' => 1,
'recording' => 1,
'release-group' => 1,
'execution' => 1
],
'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
]
);
推荐阅读
- python - 当我的代码运行时,继续收到“TypeError: unsupported operand type(s) for +: 'int' and 'str'”错误代码。谁能找出我的问题/
- swift - 线程 1 的自定义 segue 类崩溃:EXC_BAD_ACCESS (code=2, address=0x16ecb3ff0)
- java - 读入数据(Java)
- hugo - Hugo 博客 + netlify 部署 + 自定义域 = 找不到页面..令人沮丧的东西
- php - 如何手动将 WooCommerce 产品排序设置为“人气”?
- python - 在 Windows 10 上连接 jupyter notebook 远程服务器时出现问题
- typescript - 输入“部分深”
' 不可分配给类型 'Schema<{}>'。TS2345 - r - ggplot 的互相关函数 (ccf) 问题
- python - 给定一组笛卡尔点,找到将所有点连接在一起的最短总长度网络
- html - 将我的弹性项目左、中、右对齐