简体   繁体   中英

Exact match document in MongoDB

I am currently using MongoDB's driver on a Java application. Suppose I have the two following documents stored in a collection:

Document A:

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

Document B:

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

Now, I want to retrieve an exact match of DocumentB's from the collection without also returning Document A, by using key1 and key2's values, and not _id since I don't know it beforehand.

If I just use DocumentB as a query (without _id), Mongo will also return DocumentA since it has matches all the keys and values, disconsidering the fact that DocumentA has an extra key (key3).

Is there any way to perform this "exact match" query in Mongo? Will I have to implement a check afterwards?

Assuming by "exact match" you mean the document has no other fields but the ones in the query.

You will need to use aggregation framework to retrieve a list of keys in the object and filter out the ones that have unexpected keys. In mongodb syntax it can be like this:

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: []
    }
  }
])

If your matching query key:value pair has the same order than your stored documents, the aggregation below 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

Warning: These objects are equals

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

These objects are not equals

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM