Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

array with unique values over all documents of one collection

Situation: I have several documents of the same collection(account), each has an attribute of type array(string) named uniquestrings.

Problem: Each entry in uniquestrings must be unique over all documents in mongodb. It seems that MongoDB/Mongoose does not offer such a validation (neither addToSet¹ nor index: {unique: true}² solve the problem). Is there a pattern to restructure my document schema to make sure mongodb itself can validate it? At the moment the software itself checks it before updating the document.

E.g.

account {
  _id: 111,
  uniquestrings: ["a", "b", "c"]
}

account {
  _id: 222,
  uniquestrings: ["d", "e", "f"]
}

E.g. prevent account(222).uniquestrings.push("a"); by throwing a duplicate error from mongo.

¹ Uniqueness in an array is not enough
² Each item in array has to be unique across the collection

UPDATE1:

More examples. Affected Schema entry looks like:

var Account = new Schema({
    ...
    uniquestrings: [{type: String, index: {unique: true}}]
    ...
});

Now when create 4 account documents. I want only 1 and 2 be ok, and rest should fail.

var accountModel1 = new Account.Model({uniquestrings: ["a", "b"]});
accountModel1.save(); // OK
var accountModel2 = new Account.Model({uniquestrings: ["c", "d"]});
accountModel2.save(); // OK
var accountModel3 = new Account.Model({uniquestrings: ["c", "d"]});
accountModel3.save(); // FAIL => Not unique, so far so good
var accountModel4 = new Account.Model({uniquestrings: ["X", "d"]});
accountModel4.save(); // OK => But i Want this to faile because "d" is alreay in use.
like image 515
MortalFool Avatar asked Mar 23 '17 16:03

MortalFool


People also ask

How do you make an array unique in MongoDB?

ASP.NET Core 3 MVC Application with MongoDB To get unique values within two arrays in a document, use a $setUnion in aggregate(). The $setUnion takes two or more arrays and returns an array containing the elements that appear in any input array.

What is a unique value in an array?

You can find the distinct values in an array using the Distinct function. The Distinct function takes the array as an input parameter and returns another array that consists only of the unique, or non-duplicate, elements. The following example shows how to find the distinct values in an array.

How do I get distinct documents in MongoDB?

To get distinct values, use distinct() in MongoDB. It finds the distinct values for a specified field across a single collection or view and returns the results in an array.


1 Answers

It might be possible, if you are willing to store the unique values in a different collection. It would be structured like this:

{ "uniquestring" : "a", "account" : 111 }
{ "uniquestring" : "b", "account" : 111 }
{ "uniquestring" : "c", "account" : 111 }
{ "uniquestring" : "d", "account" : 222 }
{ "uniquestring" : "e", "account" : 222 }
{ "uniquestring" : "f", "account" : 222 }

I am not an expert with Mongoose, but I believe that you can define Models to link collections together, with the account field here referencing the accounts collection's _id field.

Now, you can enforce the uniqueness with a straightforward index:

db.uniquestrings.createIndex( { "uniquestring" : 1 } , { unique : true } )

Now, your app will have a little more work to do when saving the data (it needs to save to the uniquestrings collection as well as the accounts collection), but you do now have database-level enforcement of the uniqueness of these strings, across the database.

PS edits are welcome from anybody with more detailed knowledge of how to implement and use such models in mongoose.

like image 180
Vince Bowdren Avatar answered Oct 02 '22 18:10

Vince Bowdren