Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Обновить документ, если значение не соответствует

Автор вопроса: AddersОтветов: 2

Как в MongoDB пропустить обновление, если одно поле документа существует?

Чтобы привести пример, у меня есть следующая структура документа, и я хотел бы только update, если ключ link не совпадает.

{
    "_id": {
        "$oid": "56e9978732beb44a2f2ac6ae"
    },
    "domain": "example.co.uk",
    "good": [
        {
            "crawled": true,
            "added": {
                "$date": "2016-03-16T17:27:17.461Z"
            },
            "link": "/url-1"
        },
        {
            "crawled": false,
            "added": {
                "$date": "2016-03-16T17:27:17.461Z"
            },
            "link": "url-2"
        }

    ]
}

Мой запрос на обновление:

links.update({
    "domain": "example.co.uk"
    },
    {'$addToSet':
        {'good':
            {"crawled": False, 'link':"/url-1"} }}, True)

Часть проблемы заключается в том, что поле crawl может быть установлено на True или False, а дата также всегда будет разной - я не хочу добавлять в массив, если URL-адрес существует, независимо от статуса crawled.

Обновление: Просто для ясности, если URL-адрес не находится в документе, я хочу, чтобы он был добавлен в существующий массив, например, если было введено /url-3, документ будет выглядеть так:

{
    "_id": {
        "$oid": "56e9978732beb44a2f2ac6ae"
    },
    "domain": "example.co.uk",
    "good": [
        {
            "crawled": true,
            "added": {
                "$date": "2016-03-16T17:27:17.461Z"
            },
            "link": "/url-1"
        },
        {
            "crawled": false,
            "added": {
                "$date": "2016-03-16T17:27:17.461Z"
            },
            "link": "url-2"
        },
        {
            "crawled": false,
            "added": {
                "$date": "2016-04-16T17:27:17.461Z"
            },
            "link": "url-3"
        }

    ]
}

domain будет уникальным и специфичным для ссылки, и я хочу, чтобы он вставлял link в массив good, если он не существует, и ничего не делал, если он существует.

  • Почему вы используете вариант upsert? Собираетесь ли вы вставить новый документ, если совпадения нет? Также является ли домен уникальным? styvane 21.05.2016
  • Да domain будет уникальным для link - я думаю, что могу использовать его неправильно, я хочу, чтобы он вставлял ссылку в массив, если он не существует, и ничего не делал, если он существует Adders 21.05.2016

pythonmongodbmongodb-querypymongo

Ответы

Ответ 1 · рейтинг 2 · styvane

Единственный способ сделать это - найти в коллекции какой-либо документ, соответствующий вашим критериям, с помощью find_one, также вам необходимо учитывать поле "good.link" в критериях фильтрации. Если ни один документ не соответствует, вы запускаете запрос на обновление, используя update_one, но на этот раз вы не используете поле "good.link" в критериях запроса. Также вам не нужен оператор $addToSet, так как он ничего не делает просто используйте оператор обновления $push, это прояснит ваше намерение. Вам также не нужно "upsert" опцию здесь.

if not link.find_one({"domain": "example.co.uk", "good.link": "/url-1"}):
    link.update_one({"domain": "example.co.uk"},
                    {"$push": {"good": {"crawled": False, 'link':"/url-1"}}})

Ответ 2 · Tiramisu

в разделе поиска запроса вы сопоставляете все документы, где

"domain": "example.co.uk"

вам нужно добавить, что вы не хотите совпадать

'good.link':"/url-1"

поэтому постарайтесь

{
    "domain": "example.co.uk",
    "good.link": {$ne: "/url-1"}
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы