【问题标题】:Update document if value there is no match如果值不匹配,则更新文档
【发布时间】:2016-05-19 19:29:47
【问题描述】:

在MongoDB中,如果文档的一个字段存在,如何跳过更新?

举个例子,我有以下文档结构,如果link 键不匹配,我只想update

{
    "_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 字段可以设置为 TrueFalse 并且日期也总是不同 - 如果 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 将是唯一且特定于链接的,我希望它在 good 数组中插入不存在的 link,如果存在则不执行任何操作。

【问题讨论】:

  • 您为什么使用upsert 选项?如果没有匹配项,您是否打算插入新文档? “域”也是唯一的吗?
  • 是的 domain 将是 link 独有的 - 我想我可能使用不正确,如果它不存在,我希望它在数组中插入链接,如果不存在则什么也不做它确实存在

标签: python mongodb mongodb-query pymongo


【解决方案1】:

执行此操作的唯一方法是使用find_one 方法查找集合中是否有任何文档与您的条件匹配,您还需要考虑过滤条件中的“good.link”字段。如果没有匹配的文档,您可以使用update_one 方法运行更新查询,但这次您不在查询条件中使用“good.link”字段。此外,您不需要 $addToSet 运算符,因为它没有做任何简单的事情,使用 $push 更新运算符,它使您的意图清晰。您也不需要在这里“更新”选项。

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"}}})

【讨论】:

  • 行得通!虽然我需要重新添加 upsert 选项,否则它不起作用。由于它们是单独的请求,我假设您可以批量执行这些操作?
【解决方案2】:

在查询的查找部分中,您匹配所有文档,其中

"domain": "example.co.uk"

你需要添加你不想匹配的

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

所以试试

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

【讨论】:

  • 我已经更新了我的问题,希望更清楚,因为它正在添加一个新文档而不是添加到数组中
猜你喜欢
  • 1970-01-01
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
  • 2019-03-18
  • 2021-04-24
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
相关资源
最近更新 更多