【问题标题】:mongodb - ignore document if one of elements in array matches querymongodb - 如果数组中的元素之一与查询匹配,则忽略文档
【发布时间】:2018-12-24 12:02:31
【问题描述】:

我在用户集合中有一个用户对象,如下所示:

{
  "username": "bahramhasanov",
  "sessions": [
    {
      "time": "2018-12-10 12:30"
    },
    {
      "time": "2018-10-11 13:30"
    }
  ]}

现在我想获取在“2018-10-01”和“2018-10-15”之间没有任何会话的用户。 当我使用 $elemMatch 和 $not 查询时,我得到了 bahramhasanov,因为他的会话超出了此日期范围。

我使用了这个查询:

db.users.find({sessions:{$elemMatch: {"time": {$not:{$gt: ISODate('2018-10-01'),$lt: ISODate('2018-10-15')}}}}})

【问题讨论】:

标签: arrays mongodb mongodb-query


【解决方案1】:

您必须使用$not 查询运算符才能反对整个$elemMatch 运算符,而不仅仅是$lte$gte

而且时间是String而不是ISODate格式

db.collection.find({
  "sessions": {
    "$not": {
      "$elemMatch": {
        "time": {
          "$gt": ISO("2018-12-17T20:00:00.000+0000"),
          "$lt": ISO("2018-12-17T20:00:00.000+0000")
        }
      }
    }
  }
})

【讨论】:

  • 我的 mongodb 版本是 2.6 这个技巧不起作用?对此的最低要求是什么?
  • mongodb 2.6 真的已经过时了。你应该更新它
  • 我已将 mongo 更新到 3.6 但查询不起作用:{$and:[{promos:{$not:{$elemMatch:{time:{$gte:"2018-12-01",$lte:"2018-12-31"}}}}}]}
  • time 的类型是什么?
  • 如果您的时间在 ISODate 中,则使用 ISODate,如果您的时间在字符串中,则使用 String。没有别的
【解决方案2】:

要查询在某个日期范围内没有任何会话的用户,您需要先查询在该日期范围之外有会话的用户,然后再查询不在其中的用户。在您的查询中,您会获得在日期范围内拥有会话的用户,这确实会返回在日期范围内和日期范围外拥有会话的用户,并且不会返回在日期范围内的用户。在集合方面,让我们考虑

O = "在日期范围之外进行会话的用户"

I = "在日期范围内有会话的用户"

A = "所有用户"

O ∩ I = "在日期范围内外有会话的用户"

O ∪ I = "在日期范围内或外进行会话的用户"

现在,你需要

A \ O 为了做到这一点,你需要找到 O,然后从 A 中过滤掉它的项目。

【讨论】:

  • 感谢您的出色回答,但我需要一个查询:)
  • @BahramHasanov 我不是 MongoDB 专家,因此我的理论答案是,因为数学应该有效。我相信您应该有办法使用子查询将其设为单个查询。这可能会对您有所帮助:quora.com/How-do-I-perform-subqueries-in-MongoDB
猜你喜欢
  • 1970-01-01
  • 2016-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-18
  • 1970-01-01
  • 2021-02-21
  • 2021-04-16
相关资源
最近更新 更多