Check if document exists before creating a new one in MongoDB - mongodb

I am using Mongoose and NodeJS. I want to create a document, in some collection only if document in another collection exists, without making two queries to the database.
For an example lets say we have a collections of locations and apartments. Location _id is passed on the creation of a new apartment and the apartment stores it. So I want to create a document for new apartment only if location with such an _id exists.
I know that I can check for a location, using query, and then to create apartment only if the query return a result, but by this way I'am making two queries to the DB and the code becomes hard to mange.
I'am asking if there is a better way to this by telling MongoDB to do this check for me.

You'll need to make two queries.
There's no such thing as referential integrity in mongodb

Related

Collection or documents for multiple projects?

I want to manage multiple projects data in mongoDB. Each project contains multiple users from multiple departments with multiple role assigned to them. plus certain task is assigned to each user. Now I am confused about schema, not able to decide which entity should be kept as collection & which one as document ? What is the best efficient way to store ?
should I keep all under single collection as embedded documents or in separate collection ?
Thanks
First of all if you are using mongodb you should know why are you using it. MongoDB is not about normalize stuff. If you are able to create data structure is de-normalize way then and only then go for MongoDB.
I think you should maintain one single document containing all the mentioned things above. But the scenario which you have mentioned above is good for relational database. you need only 3 entities in relational database and your problem is solved.
Still if you want to go for mongodb you can go with one collection only. which contains project details number of users working there and their roles and department.

How to query MongoDB collection using mongoose discriminators

I am trying to read from a Mongo database using mongoose where the models make use of the discriminator inheritance functionality, but the documents in the DB are all inserted by another service (using the Java Mongo driver) which does not use mongoose nor its discriminators. All of my queries using subclass models (those which use the discriminator function) return empty arrays when I try to read from the DB. I think it's because mongoose is expecting those documents to contain a discriminator key, however the service which is inserting the documents has no knowledge of discriminator keys, and thus isn't setting them on the mongoDB documents.
How can I create my models and use the discriminator function such that they can still query for these documents inserted by another service?
For more context, I want to use discriminators because inheritance allows me to cleanly structure the fields of the models I'm creating and define model-specific static methods, and it lets me not write duplicate code. If there is a better way to accomplish these goals without using mongoose's built-in discriminator pattern, please share!
According to the documentation:
The way mongoose tells the difference between the different
discriminator models is by the 'discriminator key', which is __t by
default. Mongoose adds a String path called __t to your schemas that
it uses to track which discriminator this document is an instance of.
Also mongoose saves documents with discriminators to the single collections.
So, in order to have access to the documents you need to save __t parameter, and check if you save schemas with the same discriminators to a single collection

Create collections in cloudant

I'm trying to build an ionic application which retrieves data from Cloudant using pouchdb. Cloudant allows creating only databases and documents.
How can I create some collections in Cloudant?
Two part answer:
A set of documents that meet certain criteria can be considered a collection in Cloudant/CouchDB. You can create views to fetch those documents. Such a view might check for the existence of a property in a document ("all documents with a property named type"), the value of a property ("all documents with a property named type having the value of book") or any other condition that makes sense for your application and return the appropriate documents.
You basically have to follow a three step process:
determine how you can identify documents in your database that you consider to be part of the collection
create a view based on your findings in the previous step
query the view to retrieve those documents
Above documentation link provides more details.
Properties in your document can represent collections as well, as in the following example, which defines a simple array of strings.
{
"mycollectionname": [
"element1",
"element2",
...
]
}
How you implement collections really depends on your use-case scenario.
Long post, but hope that helps.
I would like to explain this with a RDBMS analogy.
In any RDBMS, a new database would mean a different connection with different set of credentials.
A collection would mean the set of tables in that particular database.
A record would mean a row in a table.
Similarly, you can look at a single Cloudant service instance as a database(RDBMS terminology).
A collection would be a "database" in that service instance in Cloudant's terminology.
A document would correpond to a single row.
Hence, Cloudant has no concept of collection as such. If you need to store your related documents in a separate collection you must do it with multiple databases within the same service instance.
If you want to use only a single database, you could create a field like "record_index" to differentiate between the different documents. While querying these documents, you could use an index. For. e.g. I have a student database. But I do not want to store the records for Arts, Commerce, Science branches in different databases. I will add a field "record_type": "arts", etc. in the records. Create an index,
{ selector: {record_type: "arts"}}
Before doing any operation on the arts records, you can use this index and query the documents. In this way, you will be able to logically group your documents.

performance difference between update_one() and insert_one() in MongoDB

I've been reading about MongoDB and realize i can insert a new document with insert_one() or with update_one(upsert = True).
since I manage my own ids, it is easier for me to query by a specific id and create the doc if not exist, without the need to handle 2 different methods (create and update).
Queries should be very fast in MongoDB, so what do i trade for this convenience?
Actually, you trade nothing. You should use insert_one() only for explicit creation of objects.

Get all usernames from a items user_id? (Mongodb query)

I am having some difficulty with my leaderboard for my application.
I have a database with two collections.
Users
Fish
In my Fish collection I also have user_id. When I fetch all fish, I get everything including user_id.
However, the user_id doesn't really help me, I want to display the username belonging to that user_id.
This is how my query looks.
Fish.find().sort({weight: -1}).limit(10).exec(function(err, leaderboard) {
if(err) return res.json(500, {errorMsg: 'Could not get leaderboard'});
res.json(leaderboard);
})
I feel like I need to make another query, to get all the usernames belonging to the user_ids I get from the first query. Perhaps use a loop somehow?
MongoDb is pretty new to me and don't really know what to look for.
Any advice, tips, link are much appriecated.
You may find useful information on MongoDB's Database References documentation.
The first thing to consider on using fields from different collections in MongoDB is:
MongoDB does not support joins. In MongoDB some data is denormalized, or stored with related data in documents to remove the need for joins. However, in some cases it makes sense to store related information in separate documents, typically in different collections or databases.
In your case, you might want to consider storing the information from the Fish collection as embedded documents within the users from the User collection.
If this is not an option, then you might want to use Manual References or loop over the user_ids provided in the result from your query over the Fish collection.
With the second option you may use a query to obtain the corresponding usernames from the User collection such as:
Users.find({user_id:<USER_ID>},{username:1})