考虑具有以下结构的文档的集合 webs

[
  {
    "_id": ObjectId("5631e7f6cc6b441000ad9033"),
    "name": "web1",
    "pagehits": [
      {
        "ip": "12.34.56.78",
        "hits": [
          ISODate("2015-10-28T11:06:37.536+0000"),
          ISODate("2015-11-28T11:06:37.536+0000")
        ]
      }
    ]
  }
]

Web(当然)有 _idname ,(其他未提及的属性)和 pagehits 数组 . 每个数组项对应一个ip . 此外,每个页面命中都会保存为 pagehit 项目的 hits 子数组中的日期 .

因此, add pagehit 函数的伪算法看起来像

  • find 网址提供 ObjectId

  • 已经有一个当前用户ip的数组项?

  • yes :将当前日期追加到已存在的 pagehits 数组元素

  • no :向 pagehits 数组附加一个新项目,其中ip是当前用户ip,而 hits 是仅包含当前日期的数组 .

是否可以通过单个MongoDB调用( findOneAndUpdate )实现此 insert hit 函数?

保证所有网络都存在,因此无需在集合中插入整个文档 .

可能发生的两种情况的示例:

Case 1) 使用IP 192.168.0.1命中(尚未列在清单中):添加了一个新的子文档

[
  {
    "_id": ObjectId("5631e7f6cc6b441000ad9033"),
    "name": "web1",
    "pagehits": [
      {
        "ip": "12.34.56.78",
        "hits": [
          ISODate("2015-10-28T11:06:37.536+0000"),
          ISODate("2015-11-28T11:06:37.536+0000")
        ]
      },
      {
        "ip": "192.168.0.1",
        "hits": [
          ISODate("2016-04-08T11:25:37.536+0000")
        ]
      }
    ]
  }
]

Case 2) 使用IP 12.34.56.78命令(已在列表中):当前日期被推送到命中数组

[
  {
    "_id": ObjectId("5631e7f6cc6b441000ad9033"),
    "name": "web1",
    "pagehits": [
      {
        "ip": "12.34.56.78",
        "hits": [
          ISODate("2015-10-28T11:06:37.536+0000"),
          ISODate("2015-11-28T11:06:37.536+0000"),
          ISODate("2016-04-08T11:25:37.536+0000")
        ]
      }
    ]
  }
]