Use MongoDB object ID as a unique key within a document - mongodb

I'm using MongoDB for my senior project to allow donors to sponsor children for an organization similar to world vision and I'm wondering about the feasibility of reusing the ObjectID datatype as a unique id within a json array.
example donor document:
{
_id: ObjectID(x), // this document's _id
name: "Josh",
last_name: "Richard",
address: "2 Happy Lane",
city: "New York",
state: "New York",
credit_card: 999999999999999,
cvv: 999,
exp: 3/18,
transactions: [
{
_id: ObjectID(x), // this is what i'm asking about
child_ids: [
ObjectID(x), // this is the _id of a doc in another collection
ObjectID(x) // this is also the _id of a doc in another collection
]
},
{
_id: ObjectID(x),
child_ids: [
ObjectID(x), // this is the _id of a doc in another collection
]
}
]
}
The transactions._id is what I'm looking for feedback on. I need this to be unique so that I can differentiate orders from each other, but I'd rather not create a new collection for storing these as documents and instead keep it all in the donor doc. Any thoughts?
EDIT: What I'm not curious about is the technical uniqueness of an ObjectID. What I'm looking to find out is if it's realistic to "repurpose" the ObjectID as a unique key to then use later in application logic. I need some way to uniquely identify objects in an array across all instances of that type of array in every document. I.E.: Every transaction needs to have it's own unique identifier and those transactions are stored in arrays in many different documents within the same collection.

Related

How to find objectId as an foreign key in mongo

How can I find the value of ObjectId in whole database for any field in mongo ,
it might be use in some collections for various fields as a reference?
"fourk_runs": [{
"Objectid": "6299b9f00f09ff045cc15d"
}],
"fourk_pass_fail": [{
"Objectid": "6299b9f00f09ff045cc152"
}],
"dr_runs": [{
"Objectid": "6299b9f00f09ff045cc154"
}],
I try this command , but it does not work
db.test.find( { $text: { $search: "4c8a331bda76c559ef04" } } )
In MongoDB, the references are mostly used for the normalization process. The references from the children's table (usually an ObjectID) are then embedded in the parent table. When reading the information, the user has to perform several queries in order to retrieve data from multiple collections.
For example, we will take the next two collections, parts and products. A product will contain many parts that will be referenced in the product collection.
parts Collection:
db.parts.findOne()
{
_id : ObjectID('1111'),
partno : '7624-faef-2615',
name : 'bearing',
price: 20,000
}
products Collection:
db.products.findOne()
{
name : 'wheel',
manufacturer : 'BMW',
catalog_number: 1134,
parts : [ // array of references to Part documents
ObjectID('1111'), // reference to the bearing above
ObjectID('3f3g'), // reference to a different Part
ObjectID('234r'),
// etc
]
}
To receive the parts for a particular product, we will first have to fetch the product document identified by the catalog number:
db.products.findOne({catalog_number: 1134});
Then, fetch all the parts that are linked to this product:
db.parts.find({_id: { $in : product.parts } } ).toArray();

MongoDB Reuse _id

Say I have a simple schema for Users, which gets an automatically generated _id:
{
_id: ObjectId("9dfhdf9fdhd90dfdhdaf"),
name: "Joe Shmoe"
}
And then I have a schema for Groups where I can add Users into a members array.
{
name: "Joe's Group",
members: [{
_id: ObjectId("58fdaffdhfd9fdsahfdsfa"),
name: "Joe Shmoe"
}]
}
Objects within an array get new autogenerated IDs, but I'd like to keep that _id field consistent and reuse it so that the member in the Group has the same attributes as they do in the Users collection.
My obvious solution is to create an independent id field in the members' User object that references their _id in the Users collection, but that seems cluttered having two separate id fields for each member.
My question is, is what I'm attempting bad practice? What's the correct way to add existing objects into a collection from another collection?
I think what you're referring to is : manual or DB References in data modelling.
original_id = ObjectId()
db.places.insert({
"_id": original_id,
"name": "Broadway Center",
"url": "bc.example.net"
})
db.people.insert({
"name": "Erin",
"places_id": original_id,
"url": "bc.example.net/Erin"
})
Check the documentation here

MongoDB Schema optimization for contacts

I am storing my contacts in mongodb like this but main drawback of this schema is I am not able to store 40k-50k contacts in one document due to limit of 16mb.
I want to change my schema now. So can anyone please suggest me best way to redesign this.
Here is my sample doucument
{
"_id" : ObjectId("5c53653451154c6da4623a77"),
"contacts" : [{
name:"",
email:"",
group:[5c53653451154c6da4623a79]
}],
"groups" : [{
_id: ObjectId("5c53653451154c6da4623a79"),
group_name:"test"
}],
}
According to you document sample, contacts belongs to a group.
In that scenario, there are different ways to end up with a better schema:
1- Document embedding:
You will have an array of contacts inside each group document.
collection groups:
{
"_id": ObjectId("5c53653451154c6da4623a79"),
"group_name":"test",
"contacts": [
{
"name":"something",
"email":"something",
},
{
"name":"something else",
"email":"something else",
}
]
}
2- Document referencing:
You will have two collections - contacts and groups - and store a group reference inside each contact.
collection contacts:
{
"_id" : ObjectId("5c53653451154c6da4623a77"),
"name":"something",
"email":"something",
"groups":["5c53653451154c6da4623a79"]
},
{
"_id" : ObjectId("5c536s7df9sd7f987d9s7d98"),
"name":"something else",
"email":"something else",
"groups":["5c53653451154c6da4623a79"]
}
collection groups:
{
"_id": ObjectId("5c53653451154c6da4623a79"),
"group_name":"test"
}
Why are we referencing group inside contact and not the contrary? Because we probably will have more contacts than groups. This way we have smaller documents with smaller "reference arrays".
The path you will follow depends a lot on how many contacts you have per group. If this number is small, I would take the Document Embedding approach, for the sake of simplicity and access easiness. If you have a large number of contacts per group, I would use Document Reference, to have smaller documents.

Get next item in MongoDB collection without ObjectId

I have access to a MongoDB collection but the entries their _id is a string, a url to be exact.
I want to retrieve the next document in a collection based on the previous _id. I looked around and I've seen it's possible using the ObjectID: Finding The Next Document in MongoDb.
My problem is that the database doesn't have ObjectID's in _id, there is also no field that could possibly be used as an alternative to ObjectID (f.e. a timestamp). So how would I retrieve the next document?
Edit: Added collection example
{ "_id": random.com,
"name": "Random",
},
{ "_id": example.com,
"name": "Example",
},
{ "_id": stack.com,
"name": "Stack",
}
If I have the _id "random.com", how do I retrieve the next document, in this case the one with _id "example.com"? I'm using pymongo.
cursor = db.coll.find({"_id": { "$gt": "the_url"}}).sort("_id").limit(1)
for doc in cursor:
print(doc['_id'])
see sort for how you could define order.
The index is alphabetical and we get next value of _id.
Still we can query for next inserted, that is about insertion time order, using sort("natural").
cursor = db.coll.find({"_id": { $gt":the_url"}}).sort("natural").limit(1)

Adding indexes in mogodb

I currently have a mongodb database which is pretty unstructured. I am attempting to extract all the followers of a given set of profiles on twitter. My database looks like this:
{'123':1
'123':2
'123':3
'567':8
'567':9
}
Where each key is a user and the value is a single follower. When I attempt to create an index on these keys, I simply run out of the available index as I have a lot of users (8 million). After googling, I find that the maximum number of indexes I can have is about 64. How do I create a proper indexing on this database? OR would you suggest a different way for me to store my data?
You should structure your data differently.
I would recommend you to have a collection of "user" documents, where every user has an array "followers". This array should be filled with unique identifiers of the users who follow (like name, _id or your own ID number).
{ name: "userA",
followers: [
"userB",
"userC"
]
},
{ name: "userB",
followers: [
"userD",
"userF"
]
},
You can then create an index on the followers field to quickly find all users who follow an other user. When you want to find all users who follow the users "userX", "userY" and "userZ", you would then do it with this query:
db.users.find({followers: { $all: ["userX", "userY", "userZ" ] } });
Edit:
To add a follower to a user, use the $push operator:
db.users.update({name:"userA"}, { $push: { followers: "userB" } } );
The $pull operator can be used to remove array enries:
db.users.update({name:"userA"}, { $pull: { followers: "userB" } } );