Access document directly by ID - mongodb

I'm used to working with firebase where I can access a document directly by fetching data from the db like so.
db.collection('collectionName/documentID').get();
I can't seem to find any documentation regarding doing something similar in mongodb. Do I have to use a find query to grab data from a mongodb or have I missed something? Thanks

I'm thinking
const collection = db.collection('collectionName');
collection.findOne({_id: ObjectId('documentID'); });

Since mongo consolse is an interactive javascript shell, One way would be to create a method similar to this:
function collectionNameGet(idToFind) {
return db.collection.find({_id: idToFind });
}

In the mongo shell you can directly get it as below:
db.st4.find({"_id" : "1234"})
Result set:
{ "_id" : "1234", "raw" : { "meas" : { "meas1" : { "data" : "blabla" }, "mesa2" : { "data" : "foo" } } } }
Or by default mongo id as:
db.st1.find({"_id" : ObjectId("5c578d57ce9ba4a066ca2fa4")})
{ "_id" : ObjectId("5c578d57ce9ba4a066ca2fa4"), "name" : "Just a name", "users" : [ "user1", "user2" ] }
For display the result in pretty format
db.st1.find({"_id" : ObjectId("5c578d57ce9ba4a066ca2fa4")}).pretty()
Result set:
{
"_id" : ObjectId("5c578d57ce9ba4a066ca2fa4"),
"name" : "Just a name",
"users" : [
"user1",
"user2"
]
}
Here st4 is my collection name in the database test, so once you are on mongo shell do the below steps before above query:
use test
db.st1.insert({"name" : "Just a name", "users" : [ "user1", "user2" ] })
and then you can query by default _id generated mongo, you can simply make a query to get the recently added documents in the collection st1 as below:
db.st1.find().sort({_id:-1}).limit(1)
Hope this will help you out to do some basic query on mongo shell

Related

MongoDB get all embedded documents where condition is met

I did this in my mongodb:
db.teams.insert({name:"Alpha team",employees:[{name:"john"},{name:"david"}]});
db.teams.insert({name:"True team",employees:[{name:"oliver"},{name:"sam"}]});
db.teams.insert({name:"Blue team",employees:[{name:"jane"},{name:"raji"}]});
db.teams.find({"employees.name":/.*o.*/});
But what I got was:
{ "_id" : ObjectId("5ddf3ca83c182cc5354a15dd"), "name" : "Alpha team", "employees" : [ { "name" : "john" }, { "name" : "david" } ] }
{ "_id" : ObjectId("5ddf3ca93c182cc5354a15de"), "name" : "True team", "employees" : [ { "name" : "oliver" }, { "name" : "sam" } ] }
But what I really want is
[{"name":"john"},{"name":"oliver"}]
I'm having a hard time finding examples of this without using some kind of programmatic iterator/loop. Or examples I find return the parent document, which means I'd have to parse out the embedded array employees and do some kind of UNION statement?
Eg.
How to get embedded document in mongodb?
Retrieve only the queried element in an object array in MongoDB collection
Can someone point me in the right direction?
Please add projections to filter out the fields you don't need. Please refer the project link mongodb projections
Your find query should be constructed with the projection parameters like below:
db.teams.find({"employees.name":/.*o.*/}, {_id:0, "employees.name": 1});
This will return you:
[{"name":"john"},{"name":"oliver"}]
Can be solved with a simple aggregation pipeline.
db.teams.aggregate([
{$unwind : "$employees"},
{$match : {"employees.name":/.*o.*/}},
])
EDIT:
OP Wants to skip the parent fields. Modified query:
db.teams.aggregate([
{$unwind : "$employees"},
{$match : {"employees.name":/.*o.*/}},
{$project : {"name":"$employees.name",_id:0}}
])
Output:
{ "name" : "john" }
{ "name" : "oliver" }

MongoDB query returning no results

I'm new to mongo and am trying to do a very simple query in this collection:
{
"_id" : ObjectId("gdrgrdgrdgdr"),
"administrators" : {
"-HGFsfes" : {
"name" : "Jose",
"phone" : NumberLong(124324)
},
"-HGFsfqs" : {
"name" : "Peter",
"phone" : "+43242342"
}
},
"countries" : {
"-dgfgrdg : {
"lang" : "en",
"name" : "Canada"
},
"-grdgrdg" : {
"lang" : "en",
"name" : "USA"
}
}
}
How do I make a query that returns the results of administrators with name like "%Jos%" for example.
What I did until now is this: db.getCollection('coll').find({ "administrators.name": /Jos/});
And variations of this. But every thing I tried returns zero results.
What am I doing wrong?
Thanks in advance!
Your mistake is that administrators is not an array, but an object with fields that are themselves objects with name field. Right query will be
{ "administrators.-HGFsfes.name": /Jos/}
Unfortunatelly this way you're only querying -HGFsfes name field, not other administrator name field.
To achieve what you want, the only thing to do is to replace administrators object by an array, so your document will look like this :
{
"administrators" : [
{
"id" : "-HGFsfes",
"name" : "Jose",
"phone" : 124324
},
{
"id" : "-HGFsfqs",
"name" : "Peter",
"phone" : "+43242342"
}
],
countries : ...
}
This way your query will work.
BUT it will return documents where at least one entry in administrators array has the matching name field. To return only administrator matching element, and not whole document, check this question and my answer for unwind/match/group aggregation pipeline.
You need to use query like this:
db.collection_name.find({})
So if your collection name is coll, then it would be:
db.coll.find({"administrators.-HGFsfes.name": /Jos/});
Look this for like query in mongo.
Also, try with regex pattern like this:
db.coll.find({"administrators..-HGFsfes.name": {"$regex":"Jos", "$options":"i"}}});
It will give you only one result because your data is not an array as below in screenshot:
If you want multiple results, then you need to restructure your data.
Ok, think i've found a better solution for you, with aggregation framework.
Run the following query on your current collection, will return you all administrators with name "LIKE" jos (case insensitive with i option) :
db.test1.aggregate(
[
{
$project: {
administrators:{ $objectToArray: "$administrators"}
}
},
{
$unwind: {
path : "$administrators"
}
},
{
$replaceRoot: {
newRoot:"$administrators"
}
},
{
$match: {
"v.name":/jos/i
}
},
]
);
Output
{
"k" : "-HGFsfes",
"v" : {
"name" : "Jose",
"phone" : NumberLong(124324)
}
}
"k" and "v" are coming from "$objectToArray" operator, you can add a $project stage to rename them (or discard if k value doesn't matter)
Not sure for Robomongo testing but in Studio 3T, formerly Robomongo, you can either copy/paste this query in Intellishell console, or copy/import in aggregation tab, (small icon 'paste from the clipboard').
Hope it helps.

Mongo db query where condition for a column (list of values) having a value

I am trying to find a way to filter the records in Mongo db using Spring query.
Here is the scenario, let's see I have an Activity entity/document. One of the fields is a list of names. I want to see if I can get all the records that the names field includes get given value, let's say "Joker".
For example, my json in Mongo is
Activity 1 -
{
"_id" : ObjectId("52c14eb92f7ceb854e445354"),
...
"names" : [{
"username" : "username1",
"realname" : "Super Man"
}, {
"username" : "username2",
"realname" : "Iron Man"
}]
}
Activity 2 -
{
"_id" : ObjectId("52c14eb92f7ceb854e445355"),
...
"names" : [{
"username" : "username3",
"realname" : "Bat Man"
}, {
"username" : "username4",
"realname" : "Joker"
}]
}
And I expect the query will let me get Activity 2 only.
Also, if possible, I prefer to use spring Mongo query in my code. Thanks in advance.
Try
db.collection.find({"names.realname": "Joker"});
I never used Spring query but should be something like
Query query = new Query();
query.addCriteria(Criteria.where("names.realname").is("Joker"));
List<MyClass> users = mongoTemplate.find(query, MyClass.class);

mongodb select using association

I have two collections, user_logs and users, user_logs documents have user_id field so I need some data from user_logs but in the same query I want to check if some other field from user related to the current user_log is empty. How should I do this?
A query can only access one collection at a time. Mongodb doesn't support joins.
They that's why they recommend that you embed the referenced data inside the document.
If the logs documents for each user isn't too big, then you can change the embed that info inside the user collection.
Giving you something like this.
Embedded User Collection:
{
user_id : "uid1",
logs : [
{ message : "Error: System shutdown", date : "2014-11-11" },
{ message : "Error: System shutdown", date : "2014-11-13" }
]
}
However, if you want to keep your current structure then you're going to have to perform two queries to find related info between the users and user_logs collections.
Example
db.user_logs.insert([
{ _id : "ul1", log : "code 1", user_id : "u1" },
{ _id : "ul2", log : "code 2", user_id : "u1" }
]);
db.users.insert([
{ _id : "u1", name : "bob", user_logs_id : "ul1" },
{ _id : "u2", name : "smith", user_logs_id : "ul2" }
]);
var userId = db.user_logs.findOne({}).user_id;
db.users.findOne({ _id : userId })
//outputs
{ "_id" : "u1", "name" : "bob", "user_logs_id" : "ul1" }

mongo - how to query a nested json

I am a complete mongo newbie. I am using mongo hub for mac. I need to query the for following json -
{ "_id" : ObjectId( "abcd" ),
"className" : "com.myUser",
"reg" : 12345,
"test" : [
{ "className" : "com.abc",
"testid" : "pqrs" } ] }
and find records where testid is pqrs. How would I go about doing that?
You can type {'test.testid': 'pqrs'} in the query field of Mongo Hub.
Looks like test is an array. If you are expecting multiple values in array you can do -
"test": {
"$elemMatch": {
"testid": "pqrs",
}
}