Mongoose find by value in array of key value pairs - mongodb

I am trying to find a document from the structure
"brandcredits": [
{
"brand_id": "5586da128a60ebcb7abeb732",
"brand_credits": 123,
"_id": "558ce2af106319b412e48b6c"
},
{
"brand_id": "5586da238a60ebcb7abeb733",
"brand_credits": 500,
"_id": "558ce2af106319b412e48b6b"
},
{
"brand_id": "558b382e7881f424154d6c27",
"brand_credits": 500,
"_id": "558ce2af106319b412e48b6a"
},
{
"brand_id": "558b38467881f424154d6c28",
"brand_credits": 500,
"_id": "558ce2af106319b412e48b69"
},
{
"brand_id": "558b38687881f424154d6c29",
"brand_credits": 245,
"_id": "558ce2af106319b412e48b68"
}
]
My mongoose query is
BrandInfo.find({'_id':{$in: user[0].brandcredits.brand_id}},function(err,active){
console.log(active);
});
Which returns undefined
I need to query a schema with the array of brand_id.
How do I do that?
Any help would be much appreciated.
Thanks

What you're doing is searching for _id in user[0].brandcredits.brand_id which doesn't work, or even make sense because user[0].brandcredits.brand_id itself is just another ObjectID.
What you need to be searching for is: brand_id in user[0].brandcredits
So try this:
BrandInfo.find( { 'brand_id': {$in: user[0].brandcredits} } , function(err, active){
console.log(active);
});

Related

Populate Search MongoDB Objects

Can you please tell me how to search for a nested object (only _id appears in it and is expanded via .populate() )?
I need to search by title and album.title, how can I do this?
async getAll(searchTerm?: string) {
let options = {}
if (searchTerm) {
options = {
$or: [
{
title: new RegExp(searchTerm.trim(), 'gi'),
},
],
}
}
return this.TrackModel.find(options)
.select('-updatedAt -__v')
.sort({ createdAt: 'desc' })
.populate('album author')
.exec()
}
image of JSON below
[
{
"_id": "638cec330c055283f3eeb227",
"poster": "/uploads/tracks/Coolio/Coolio-cover.jpg",
"title": "Gangsta's Paradise",
"slug": "gangstasparadise",
"duration": 240,
"countPlays": 7269322,
"trackUrl": "/uploads/tracks/Coolio/Coolio - Gangstas Paradise.mp3",
"album": [
{
"_id": "638ceb960c055283f3eeb225",
"title": "Gangsta's Paradise",
"slug": "gangstasparadise",
"poster": "/uploads/tracks/Coolio/Coolio-cover.jpg",
"author": [
"638ce9f50c055283f3eeb223"
],
"createdAt": "2022-12-04T18:48:54.306Z",
"updatedAt": "2022-12-04T18:48:54.306Z",
"_v": 0
}
]
}
]
I tried to search using $or, but I ran into a problem that at the time of the search, only _id is stored in the album array.

modifiedCount is 1 even though the document didn't change

I am using a simple updateOne query where I pull an ObjectId out of an array.
await this.portfolioModel.updateOne(
{
_id: portfolioId,
'watchlist.custom._id': watchlistId
},
{
$pull: {
'watchlist.custom.$.assets': assetId
}
}
)
But I want to detect if the document actually changed or if the assetIds wasn't in the array to begin with. The problem is that even though the document hasn't changed MongoDB still returns modifiedCount with 1.
{
acknowledged: true,
modifiedCount: 1,
upsertedId: null,
upsertedCount: 0,
matchedCount: 1
}
I checked the document and the __v doen't increment with the updates so I don't know why MongoDB thinks the document has changed.
This is how the document looks (before and after update):
{
"_id": {
"$oid": "600188dab0b1c70050084e3e"
},
"watchlist": {
"all": [],
"custom": [
{
"assets": [],
"_id": {
"$oid": "624d7a18c89b3937212b3a55"
}
}
]
},
"__v": 18,
"createdAt": {
"$date": "2021-05-11T22:19:05.450Z"
},
"updatedAt": {
"$date": "2022-04-06T11:45:37.415Z"
}
}
I encountered this same issue using mongoose 6.3.5 and MongoDB serverless version 5.3.1.
The fix for me was removing {timestamps: true} from my schema. This causes the document to be 'modified' even if no change was made to its values. I believe it is because the 'updatedAt' value would change whenever updateOne() would access the document.

MongoDB query using intersection of 2 lists

I'm working on a project where we use mongodb 4.4 as our database. The problem is I have to make a query that is too complicated using mongo query language.
That's an exemple of the data in the database:
{
"neededQuantity": 100,
"auth": {
"groups": ["group-1"]
},
"createTime": "2022-02-03T14:17:25.809704600Z",
},
{
"neededQuantity": 120,
"auth": {
"groups": ["group-3"]
},
"createTime": "2022-02-02T14:17:25.809704600Z",
},
{
"neededQuantity": 150,
"auth": {
"groups": ["group-2","group-1"]
},
"createTime": "2022-02-01T14:17:25.809704600Z",
}
The query has to find the documents that have at least 1 element of the list auth.groups in common with an another list that is given as input.
If the input list is ["group-1"], the query result should be:
{
"neededQuantity": 100,
"auth": {
"groups": ["group-1"]
},
"createTime": "2022-02-03T14:17:25.809704600Z",
},
{
"neededQuantity": 150,
"auth": {
"groups": ["group-2","group-1"]
},
"createTime": "2022-02-01T14:17:25.809704600Z",
}
How can I do it?
Thank you very much in advance.
you can do it with $in
db.collection.find({
"auth.groups": {$in: ["group-1"]}
})
playground
more detail about $in here

Move data from inside nested array

I have inserted multiple documents in my Mongo database incorrectly. I have accidentally nested the data inside another data object:
{
"_id": "5cdfda8ddc5cf00031fd3949",
"payload": {
"timestamp": "2019-05-18T10:12:29.896Z",
"data": {
"data": {
"name": 10,
"age": 10,
}
}
},
"__v": 0
}
I would like the document to not have the extra data object. So I would like it to look like this:
{
"_id": "5cdfda8ddc5cf00031fd3949",
"payload": {
"timestamp": "2019-05-18T10:12:29.896Z",
"data": {
"name": 10,
"age": 10,
}
},
"__v": 0
}
Is there a way in Mongo for me to update all the documents that have 2 data objects to just have one like shown above?
Alas, you cannot do this with one database request. You have to loop over all documents programmatically, set the new data and update them in the database.
You could use the aggregation framework, which won't let you update in place, but you could use the $out operator to write the results to a new collection, if that's an option.
db.collection.aggregate([
{
$project: {
__v : 1,
"payload.timestamp" : 1,
"payload.data" : "$payload.data.data"
},
},
{
"$out": "newCollection"
}
])
Or if you have a mixture of docs with correct format and docs with incorrect format, you can use the $cond operator to determine the correct output:
db.collection.aggregate([
{
$project: {
__v : 1,
"payload.timestamp" : 1,
"payload.data" : {
$cond: [
{ $ne : [ "$payload.data.data", undefined]},
"$payload.data.data",
"$payload.data"
]}
}
},
{
"$out": "newCollection"
}
])

why isnt mongo returning object in array?

I'm searching for documents that contain a particular _id in the contacts array in the document. So here's the structure:
{
"_id": ObjectId("505c2daea9d397f2260001cd"),
"contacts": [
{
"userGroupId": ObjectId("50422b53743d6c7c0e000000"),
"userId": ObjectId("5061f8c66096eee07d000008")
},
{
"userGroupId": ObjectId("505bf9476096ee990200000e"),
"userId": ObjectId("505c2daea9d397f2260001ce")
},
{
"userGroupId": ObjectId("50422b75743d6c700e000004"),
"userId": ObjectId("506cff736096ee1e26000384")
},
{
"userGroupId": ObjectId("50422b66743d6c6b0e000000"),
"userId": ObjectId("505c2daea9d397f2260001cf")
},
{
"userGroupId": ObjectId("5050e86aa9d3977b67000000"),
"userId": ObjectId("506494ef6096ee021f000064")
},
{
"userGroupId": ObjectId("50422b53743d6c7c0e000000"),
"userId": ObjectId("504d72246096ee2348000008")
},
{
"userId": ObjectId("50735e8e6096ee7c510002b9"),
"userGroupId": ObjectId("5046c73e6096ee1b77000001")
}
]
}
Here's a second document:
{
"_id": ObjectId("505c2da0a9d397f2260000b7"),
"contacts": [
{
"userGroupId": ObjectId("50422b66743d6c6b0e000000"),
"userId": ObjectId("505c2da0a9d397f2260000b8")
},
{
"userId": ObjectId("5061f8c66096eee07d000008"),
"userGroupId": ObjectId("50422b53743d6c7c0e000000")
},
{
"userId": ObjectId("50735e8e6096ee7c510002b9"),
"userGroupId": ObjectId("5046c73e6096ee1b77000001")
}
]
}
You'll notice that both documents have a userId of ObjectId("50735e8e6096ee7c510002b9") in them. I run this command:
db.collection.find({ 'contacts':
{$elemMatch: { userId: ObjectId("50735e8e6096ee7c510002b9") } }
});
Which should (I think) return both documents. But it only returns the second document. Not the first. I have also tried:
db.collection.find({'contacts.userId': ObjectId("50735e8e6096ee7c510002b9") });
which does the same thing as the $elemMatch query.
I'm probably missing something really elementary, but if you guys could offer some advice I'd really appreciate it.
This was a problem with the application layer it turns out, not Mongo. One of the records was numerically keyed, the other was not, I just had been working with Rock Mongo which seems to key all the arrays.
Thanks for your help JohnnyHK