Обновить или вставить документ с помощью оператора $ в MongoDB - PullRequest
0 голосов
/ 09 апреля 2020

У меня есть база данных, где общая форма документов выглядит так

    id: String,
    day: Number,
    counter: Number
    arrs: [{
        name: String,
        hr: Number,
        stuff: {}
    }]

Так что я буду создавать / обновлять новый документ для каждого нового дня и для каждого нового часа и каждого имени, поэтому то, что я хочу использовать, это fineOneAndUpdate, где я проверяю, равен ли id идентификатору, совпадает ли день с текущим днем, совпадает ли hr с текущим hr, и совпадает ли имя с объектом I хочу обновить. Затем я хочу увеличить stuff, который может содержать символы подстановки. Итак, запрос, который у меня сейчас есть, таков:

    Site.findOneAndUpdate({id: 123456, day: 1586390400, "arrs.hr": 16, "arrs.name": "Bob"},{
        $inc: {
            counter: 1,
            "arrs.$.stuff.${wildcardname}": 1
        }
    },
    {
        upsert: true
    }, function(err, result){
        if (err) {
            console.log(err)
        }
    });
}

Итак, если у меня есть пустой БД, я ожидаю получить этот документ после запроса выше

    id: 123456,
    day: 1586390400,
    counter: 1
    arrs: [{
        name: "Bob",
        hr: 16,
        stuff: {wildcardname: 1}
    }]

Так что если бы я запустите его снова (в течение того же дня + hr + name) с другим wildcardname Я бы просто обновил документ выше, чтобы он превратился в

    id: 123456,
    day: 1586390400,
    counter: 2
    arrs: [{
        name: "Bob",
        hr: 16,
        stuff: {wildcardname: 1, wildcardname2: 1}
    }]

Но я продолжаю получать Error: The positional operator did not find the match needed from the query.. Поэтому после некоторых исследований я нашел это в документах

Не используйте позиционный оператор $ с операциями upsert, потому что вставки будут использовать $ как имя поля во вставленном документе.

Но я не совсем уверен, как иначе сделать это иначе. Я не хочу делать 2 звонка, чтобы проверить, существует ли документ, и создаю его, и еще один, чтобы обновить, если он существует.

Любая помощь будет оценена!

1 Ответ

0 голосов
/ 10 апреля 2020

Оператор $ относится к указанному элементу массива c, который соответствует запросу. Если не было сопоставленного документа, то не было сопоставленного элемента, поэтому нельзя ожидать, что он будет ссылаться на что-либо.

Если вы используете MongoDB 4.2+, вы можете использовать форму конвейера команды update и определить конвейер, который будет создавать массив, если он не существует, или найти и обновить элемент, если он существует. Upsert пропустит вновь созданный документ по конвейеру.

Если вы используете более старую версию, вам нужно будет запустить ее как обновление без upsert и проверить количество подходящих документов, затем вставить документ отдельно, если ничего не найдено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...