MongoDB - использование $addToSet для добавления значения в массив на основе совпадения идентификатора
Я создаю приложение с использованием MongoDB Realm. В приложении хранится информация о спортивных карточках пользователя (каждая из которых имеет
cardId
уникальный для этого пользователя) в одной коллекции, а затем отправляется и получает заполненные списки ebay, связанные с каждой картой (с использованием названия, имени игрока и т. д. из записи), и сохраняет эти данные в отдельной коллекции Mongo, а также
cardId
.
Этот процесс работает (возможно, несмотря на мой дрянной код!), А документ в Mongo выглядит так:
{
"_id": {
"$oid": "5f6a5bda82c81067eac32da6"
},
"itemId": "174428279769",
"cardId": [
"Was-Ant-5281"
],
"galleryURL": "https://thumbs2.ebaystatic.com/m/m1heSnR2qz5NbPw7mCxQhkg/140.jpg",
"title": "2020 Black Silver Ink 3-Color Rookie Patch Auto #229 Antonio Gibson #54//99"
}
Поскольку возможно, что другой пользователь сгенерирует запрос API ebay, который вернет тот же ebay
itemId
, в моем коде я пытаюсь проверить, существует ли запись с тем же
itemId
и если он добавит
cardId
в массив, а не создавать новый документ.
Я читал несколько похожих вопросов по SO, которые предполагают, что я могу использовать
$addToSet
с участием
$set
но когда я пытаюсь это сделать, я получаю такие ошибки, как
uncaught promise rejection: multiple write errors: [{write errors: [{Updating the path 'cardId' would create a conflict at 'cardId'}]}, {<nil>}]
.
Полный код ниже - может кто-нибудь посоветовать, как это сделать правильно?
exports = async function(payload) {
const axios = require("axios");
const mongodb = context.services.get("mongodb-atlas");
const eventsdb = mongodb.db("cards");
const eventscoll = eventsdb.collection("ebay-prices");
//////////// Get a list of a users cards from the cards collection
var collection = context.services.get("mongodb-atlas").db("cards").collection("stuart collection");
var ownedCards = await collection.find({
forTrade: "Yes"
}).toArray();
for (let card of ownedCards) {
// make the ebay API call based on card brand, card series and player name
let url = "http://svcs.ebay.com/services/search/FindingService/v1?GLOBAL-ID=EBAY-US&REST-PAYLOAD&keywords=" + card.brand + " " + card.series + " " + card.player +
"&itemFilter(0).name=SoldItemsOnly&itemFilter(0).value=true&OPERATION-NAME=findCompletedItems&paginationInput.entriesPerPage=6&paginationInput.pageNumber=1&RESPONSE-DATA-FORMAT=json&SECURITY-APPNAME=<MyAPPID>&SERVICE-NAME=FindingService&SERVICE-VERSION=1.12.0";
let cardId = card.card_id;
axios
.get(url)
.then(resp => {
for (const item in resp.data.findCompletedItemsResponse[0].searchResult[0].item) {
const itemId = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].itemId[0];
const title = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].title[0];
const galleryURL = resp.data.findCompletedItemsResponse[0].searchResult[0].item[item].galleryURL[0];
const result = eventscoll.updateOne({
itemId: itemId
}, {
// $addToSet: { cardId: { $each: cardId } },
$set: {
itemId: itemId,
title: title,
cardId: [cardId],
galleryURL: galleryURL
}
}, {
upsert: true
})
}
})
}
};