Я не могу заставить оператор $ set работать с указанным c полем - PullRequest
0 голосов
/ 31 марта 2020

Я пишу базу данных для нашей игры. Последние три дня я боролся с этим вопросом. Что бы я ни пытался, я не могу заставить оператор $set работать на одном поле. Всего один.

У меня есть коллекция GlobalLeaderboard, где каждый документ содержит эту структуру:

{
    "_id" : { "$oid" : "5e7d445f5010bb548850d2ee" },
    "PlayerName" : "Regen_erate",
    "Rating" : 38.24,
    "TotalMapsPlayed" : 372,
    "UserId" : "P526993347"
}

Код Node.js, который я запускаю для редактирования базы данных, выглядит следующим образом:

rating = await getRating(Plays.find({"UserId": newPlayData.UserId}).sort({"Rating": -1}));
console.log(rating);
Global.findOneAndUpdate({"UserId": newPlayData.UserId}, 
            {
                $inc: {"TotalMapsPlayed": 1},
                $set: {"PlayerName": newPlayData.PlayerName},
                $set: {"Rating": rating.toFixed(2)},
                $set: {"UserId": newPlayData.UserId}
            },
            {
                upsert: true,
                bypassDocumentValidation: true,
                ignoreUndefined: true
            }).catch(err => {
                console.log("ERR: " + err);
                res.status(500).send("Whoops! Something went horribly wrong! Here's some info: " + err);
            });

Даже если я вставлю случайное число (double) в операцию $set, оно все равно не будет обновляться. Кажется, это происходит без всякой причины ...

Я могу запустить $set на всех других полях, кроме поля Rating. Из любопытства я попытался использовать $inc на поле, о котором идет речь, и, к удивлению, смог заставить его работать. Что происходит?

1 Ответ

0 голосов
/ 31 марта 2020

Второй аргумент findOneAndUpdate является объектом. У объекта может быть только 1 экземпляр указанного c имени поля. Когда вы указываете одно и то же поле несколько раз, последним является оставшееся значение. Итак, ваш документ обновления:

           {
                $inc: {"TotalMapsPlayed": 1},
                $set: {"PlayerName": newPlayData.PlayerName},
                $set: {"Rating": rating.toFixed(2)},
                $set: {"UserId": newPlayData.UserId}
            }

Эквивалентно

           {
                $inc: {"TotalMapsPlayed": 1},
                $set: {"UserId": newPlayData.UserId}
            }

Чтобы задать несколько полей в одном обновлении, перечислите все поля в одном $set, например:

           {
                $inc: {"TotalMapsPlayed": 1},
                $set: {"PlayerName": newPlayData.PlayerName,
                       "Rating": rating.toFixed(2),
                       "UserId": newPlayData.UserId}
            }
...