Using $redact we can restrict the content of document on the basis of information stored in document themselves.
For example a collection named Inventory which have following structure.
Run following script.
use Test |
db.Inventory.insert( { "Title":"MongoDB Tutorial by codefari.com", "ISBN":"1990987666765", "AccessCountry":["India","China"], }) db.Inventory.insert( { "Title":"SQL Server tutorial by codefari.com", "ISBN":"9909876765476", "AccessCountry":["USA"], }) db.Inventory.insert( { "Title":"C# tutorial by codefari.com", "ISBN":"8898877676544", "AccessCountry":["UK"], }) db.Inventory.find() |
output
/* 0 */ { "_id" : ObjectId("5655b294583c040b3341b96e"), "Title" : "MongoDB Tutorial by codefari.com", "ISBN" : "1990987666765", "AccessCountry" : [ "India", "China" ] } /* 1 */ { "_id" : ObjectId("5655b294583c040b3341b96f"), "Title" : "SQL Server tutorial by codefari.com", "ISBN" : "9909876765476", "AccessCountry" : [ "USA" ] } /* 2 */ { "_id" : ObjectId("5655b294583c040b3341b970"), "Title" : "C# tutorial by codefari.com", "ISBN" : "8898877676544", "AccessCountry" : [ "UK" ] } |
See content "AccessCountry" we want to filter content on the behalf of country means a user belong to country USA can't see the other content except "AccessCountry", "USA" at this level we can use $redact.
See below query.
var userAccess=["India","USA"]; db.Inventory.aggregate( [{ $redact:{ $cond: { if: { $gt: [ { $size: { $setIntersection: [ "$AccessCountry", userAccess ] } }, 0 ] }, then: "$$DESCEND", else: "$$PRUNE" } } }]) |
output
{ "result" : [ { "_id" : ObjectId("5655b294583c040b3341b96e"), "Title" : "MongoDB Tutorial by codefari.com", "ISBN" : "1990987666765", "AccessCountry" : [ "India", "China" ] }, { "_id" : ObjectId("5655b294583c040b3341b96f"), "Title" : "SQL Server tutorial by codefari.com", "ISBN" : "9909876765476", "AccessCountry" : [ "USA" ] } ], "ok" : 1 } |