【问题标题】:Exact match document in MongoDBMongoDB 中的完全匹配文档
【发布时间】:2020-06-18 03:42:11
【问题描述】:

我目前在 Java 应用程序上使用 MongoDB 的驱动程序。假设我将以下两个文档存储在一个集合中:

文件 A:

{
  "_id": "something",
  "key1": "Value1",
  "Key2": "Value2",
  "Key3": "Value3"
}

文档 B:

{
  "_id": "somethingDifferent",
  "key1": "Value1",
  "Key2": "Value2"
}

现在,我想通过使用 key1 和 key2 的值​​而不是 _id 从集合中检索 DocumentB 的完全匹配,而不返回 Document A,因为我事先并不知道。

如果我只使用 DocumentB 作为查询(没有 _id),Mongo 也会返回 DocumentA,因为它匹配所有的键和值,忽略 DocumentA 有一个额外的键 (key3) 的事实。

有没有办法在 Mongo 中执行这个“完全匹配”查询?之后我需要进行检查吗?

【问题讨论】:

  • 您可以使用_id(如果您知道它的值)来获得任何文档的完全匹配。文档 B 是否有一个名为“”key3 的字段?
  • 我事先不知道_id。我只想查询 key1 和 2。

标签: java mongodb


【解决方案1】:

假设“完全匹配”是指文档除了查询中的字段外没有其他字段。

您将需要使用聚合框架来检索对象中的键列表并过滤掉具有意外键的键。 在 mongodb 语法中可以是这样的:

db.collection.aggregate([
  {
    $match: {
        "key1": "Value1",
        "Key2": "Value2"
    }
  },
  {
    $addFields: {
      extra_keys: {
        $setDifference: [
          {
            $map: {
              input: {
                $objectToArray: "$$ROOT"
              },
              in: "$$this.k"
            }
          },
          [                   // <== the list of keys in the query
            "_id",
            "key1",
            "Key2"
          ]
        ]
      }
    }
  },
  {
    $match: {
      extra_keys: []
    }
  }
])

【讨论】:

  • 我真的需要这个 JSON 中的所有内容吗?我在 Mongo 中不是很有经验,但在我看来,在这种情况下有很多没有用的东西(比如最后一个 $match 对象)。
  • 最后一个 $match 是过滤掉带有额外字段的文档的那个。
  • 您知道如何使用 Java 执行此操作吗?你在那里为它写下了 JSON。在 Java 中,我们使用对象进行查询。如果没有,我会自己寻找Java中的聚合框架。谢谢你的回答。我会先对其进行测试,然后再将其标记为正确。
  • 不幸的是,我对 Java 的了解不够好,无法提供答案。 mongodb.github.io/mongo-java-driver/3.12/builders/aggregation 应该给出一些关于管道阶段的想法,并且函数应该是简单的文档,例如new Document("$setDifference", Arrays.asList(...))new Document("$map", ....)
【解决方案2】:

如果您的匹配查询key:value对与您存储的文档具有相同的顺序,则may work with $eq operator下方的聚合。

db.collection.aggregate([
  {
    $match: {
      $expr: {
        $eq: [
          {
            "key1": "Value1",
            "Key2": "Value2"
          },
          {
            $arrayToObject: {
              $filter: {
                input: {
                  $objectToArray: "$$ROOT"
                },
                cond: {
                  $ne: [
                    "$$this.k",
                    "_id"
                  ]
                }
              }
            }
          }
        ]
      }
    }
  }
])

MongoPlayground

警告:这些对象是相等的

{                          {
  "key1": "Value1"   ----      "key1": "Value1",
  "Key2": "Value2",  ----      "Key2": "Value2"
}                          }

这些对象等于

{                          {
  "key1": "Value1"   --/-      "Key2": "Value2",
  "Key2": "Value2",  -/--      "key1": "Value1"
}                          }

【讨论】:

    猜你喜欢
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多