MongoDB query: all documents that contain reference to a specific id - mongodb

I am trying to extract some data from a legacy mongo db (v. 2.0.4). I have data that is structured like this:
{"_id": "1",
"#graph": {"ma:isMemberOf": [{"#id": "524224b804743b02a4c23488",
"title": "IHum 350",
"transcript": "False"},
{"#id": "53cfd59404743bc3c9119adf",
"restrictor": "578e89ae04743b7b0816beff",
"title": "Spanish 339",
"transcript": "False"}],
"ma:title": "Toy title 1"},
"_id": "2",
"#graph": {"ma:isMemberOf": [{"#id": "524224b804743b02a4c23488",
"title": "IHum 350",
"transcript": "False"}],
"ma:title": "Toy title 2"}}
...and I want to write a query that will find all of the documents that are members of a particular group (matching the #id field). For example, I want to be able to search for 524224b804743b02a4c23488 and receive documents 1 and 2. Or to search for 53cfd59404743bc3c9119adf and receive only document 1.
I have tried several things, but I can't figure out how to query embedded objects.

db.collection.find({
"#graph.ma:isMemberOf.#id": <your query>
})
Here is the Mongo playground for your reference.

Related

Count document satisfies criteria in MongoDB Compass

Below one of the document inside my test.users collection.
{
"_id": {
"$oid": "62ef8c502935226353a97efb"
},
"workspaces": [
{
"$oid": "62ef8c722935227aaca97eff"
}
],
"emailConfirmed": true,
"ipInfo": {
"ip": "191.23.43.218",
"region": "Krasnodarskiy",
"country": "RU",
"timezone": "Europe/Moscow"
},
"__v": 0
}
I want to count the number of country of RU in test.users collection in MongoDB compass, how should I do it? I only saw filter, project, sort, collation under Documents as follows in Mongo DB compass, is there a way I can directly enter a mongoDB query?
You can use the mongosh shell present below, or you can directly check the count below FIND button after running your query, text is like Displaying document x of y:

Is updating Embedded Documents in MongoDB a Manual process?

I am not overly familiar with Mongodb yet , but I have a question about embedded documents.
I have seen a number of posts which show you how to update embedded documents through some update query.
My question is this: If I have a collection with embedded documents - which is denormalised for performance ; and one of the embedded documents changes, then do I need to manually update all the embedded documents or is there some way of specifying the link in MongoDB to Auto-Update?
For Example:
An Order record might look like the structure below. Note there is a Product item in one of the rows.
Lets say the ItemName field changed to "Product1a" in the product from a different collection and I want to update the product in every single order where this exists. Is that a manual process - or is there a way od setting it up in Mongodb to auto-update embedded documents?
{
"id": "ccc1beb1-e022-11e9-97f0-e7e789106ab2",
"type": "order",
"orderNumber": "ORD-100209857x",
"orderDate": "2019-09-26T17:42:31.000+12:00",
"orderItems": [
{
"discount": 0,
"price": 24.4944,
"product": {
"id": "ccc1beb1-e022-11e9-97f0-e7e789106ab2",
"itemNumber": "prd1",
"itemName": "Product1"
},
"qty": 4,
"rowTotal": 97.96,
"taxAmount": 9.8
},
{
"discount": 0,
"price": 3.21,
"itemName": "Shipping",
"qty": 1,
"rowTotal": 3.21,
"taxAmount": 0
}
]
}
Not sure what you mean by manual process, but here is some sample code to update all the documents
db.collection.updateMany({}, {$set:{"orderItems.product.itemName": "updatedProductName"}})
Let me know if this is not what you are looking for.

How to connect to collections by nested fields in MongoDB

I am struggling with some query in MongoDB. Let's say I have standings collection which looks like
{
"competitions: {id: "1", name:"someLeague"},
"standings": [
{
"type": "TOTAL",
"table": [
{
"position": "1",
"team": {
"id": "123",
"name": "XYZ"
},
won: "1",
draw: "2",
lost: "3",
points: "4",
},
{
"position": "2",
"team": {
"id": "321",
"name": "ABC"
}
...
And the fixtures collection which looks like
{
matchDay: "YYYY-MM-DD",
homeTeam: {id: "123", name:"ABC"},
awayTeam: {id: "321", name:"XYZ"},
}
Is it possible to connect this two collection this way that field "homeTeam" in fixtures collection will contain all information including points, won games etc. from standings where type would be total? And same thing with the field awayTeam, with the proviso that information of team would be from array where standings type is away.
There is no means in MongoDB to reference a document of collection A in collection B so that find queries on collection B automatically provide attributes of the referenced document. However, as of MongoDB 3.2 it is possible to use $lookup command as part of an aggregation (see https://stackoverflow.com/a/33511166/3976662) to JOIN (similar to standard SQL) over multiple collections during the query. In your case, you can consider using $lookup in conjunction with $unwind - similar to the example in the MongoDB docs. Spring Data Mongo supports $lookup since 1.10.

Querying MongoDB (Using Edge Collection - The most efficient way?)

I've written Users, Clubs and Followers collections for the sake of an example the below.
I want to find all user documents from the Users collection that are following "A famous club". How can I find those? and Which way is the fastest?
More info about 'what do I want to do - Edge collections'
Users collection
{
"_id": "1",
"fullname": "Jared",
"country": "USA"
}
Clubs collection
{
"_id": "12",
"name": "A famous club"
}
Followers collection
{
"_id": "159",
"user_id": "1",
"club_id": "12"
}
PS: I can get the documents using Mongoose like the below way. However, creating followers array takes about 8 seconds with 150.000 records. And second find query -which is queried using followers array- takes about 40 seconds. Is it normal?
Clubs.find(
{ club_id: "12" },
'-_id user_id', // select only one field to better perf.
function(err, docs){
var followers = [];
docs.forEach(function(item){
followers.push(item.user_id)
})
Users.find(
{ _id:{ $in: followers } },
function(error, users) {
console.log(users) // RESULTS
})
})
There is no an eligible formula to manipulate join many-to-many relation on MongoDB. So I combined collections as embedded documents like the below. But the most important taks in this case creating indexes. For instance if you want to query by followingClubs you should create an index like schema.index({ 'followingClubs._id':1 }) using Mongoose. And if you want to query country and followingClubs you should create another index like schema.index({ 'country':1, 'followingClubs._id':1 })
Pay attention when working with Embedded Documents: http://askasya.com/post/largeembeddedarrays
Then you can get your documents fastly. I've tried to get count of 150.000 records using this way it took only 1 second. It's enough for me...
ps: we musn't forget that in my tests my Users collection has never experienced any data fragmentation. Therefore my queries may demonstrated good performance. Especially, followingClubs array of embedded documents.
Users collection
{
"_id": "1",
"fullname": "Jared",
"country": "USA",
"followingClubs": [ {"_id": "12"} ]
}
Clubs collection
{
"_id": "12",
"name": "A famous club"
}

Mongodb query for arrays of combination two fields

Say I have a document in the database:
{"name": "Jason", "score": 20, "color": "blue"}
And I have an array of data that contains documents with name and score, is there a way for me to query for the combination of the name and score via $in? For example, if I had a list that looked like
var data = [
{"name": "Bob", "score": 12}
{"name": "Jason", "score": 20}
{"name": "Tammy", "score": 19}
];
And I wanted to query the collection to see if any combination of name and score found within data existed within said collection, how could I do that?
Close because $in is actually a shortened form of $or. You already have the array there so:
db.collection.find({ "$or": data })