I am trying to query a list of documents where a userid DOES NOT exist inside an array of objects.
The database (documents) looks like this:
[
{
title: 'object 1',
description: 'description 1',
members: [
{ profile: { id: '123', ...}, data: {} },
{ profile: { id: 'abc', ...}, data: {} },
{ profile: { id: 'def', ...}, data: {} },
]
},
{
title: 'object 2',
description: 'description 3',
members: [
{ profile: { id: 'aaa', ...}, data: {} },
{ profile: { id: 'bbb', ...}, data: {} },
{ profile: { id: 'ccc', ...}, data: {} },
]
},
]
Given that my userid is 'aaa' I am trying to query all documents where I am NOT a member.
I can successfully query all documents where my userid exists using this code:
await this._repository.findManyByQuery(
{
members: {
$elemMatch: {
"profile.id": "aaa",
},
},
},
)
However I am looking to query all objects where my ID DOES NOT exist. I have tried using $ne however it still returns the documents where the user id exists
members: {
$elemMatch: {
"profile.id": { $ne: "aaa" },
},
},
I guess I am looking for the opposite of $elemMatch but for querying inside an arry
You can use $not to negate the $elemMatch like this:
await this._repository.findManyByQuery({
members: {
"$not": {
$elemMatch: {
"profile.id": "aaa"
}
}
}
})
Example here
Related
the present Object is :-
{
_id: "abc12344",
renderId: '123456789',
concernTo: [{
name: 'vijay 4',
id: 'snhdkjn786786',
commons: []
},
{
name: 'ak',
id: 'sdkfg787877',
commons: []
}
]
}
Output needs to be like:
{
_id: "abc12344",
renderId: '123456789',
concernTo: [{
name: 'vijay 4',
id: 'snhdkjn786786',
commons: [{to: "xyz", from:"abc"}, {to: "xyz", from:"abc"}]
},
{
name: 'ak',
id: 'sdkfg787877',
commons: []
}
]
}
So need to push data in concernTo in commons field
In query i'm trying to search by renderId and id in "concernTo" array field and trying to update the object.
Query for that:---
let obj = { to: "xyz", from: "abc" };
let filter = {
renderId: "123456789",
"concernTo.id": "snhdkjn786786",
};
let update = {
$push: {
"concernTo.id.$": { subComment: obj },
},
};
let doc = await blogsCommentModel.findOneAndUpdate(filter, update, {
returnOriginal: false,
});
console.log(doc);
You want to be using arrayFilters for this, like so:
let doc = blogsCommentModel.findOneAndUpdate(filter,
{
"$push": {
"concernTo.$[elem].commons": obj
}
},
{
arrayFilters: [
{
"elem.id": "snhdkjn786786"
}
]
})
Mongo Playground
ids = 602bc4c1a7fe3222c48b4efc
email = anartoflijkjk67g6#gmail.com
const Order = await User.aggregate([
{ $match: { email } },
{ $unwind: '$orders' },
{ $set: { _id : ids, "orders.orderStatus": "Paid" } }
])
I get an error while trying to update
code: 40324
codeName: "Location40324"
name: "MongoError"
ok: 0
My DB JSON
{ 14:46:51
comments: [],
orders: [
{
_id: 602bc4c1a7fe3222c48b4efc,
shares: 111,
userName: '111',
orderCreationDate: 2021-02-16T13:12:33.176Z,
orderStatus: 'In Cart',
totalOrderValue: 555100
},{
_id: 0000000000000001,
shares: 111,
userName: '1112',
orderCreationDate: 2021-02-16T13:12:33.176Z,
orderStatus: 'In Cart',
totalOrderValue: 55500
}
],
tikTokAccounts: [],
tikTokVideos: [],
paymentCards: [],
_id: 602bc0e024e05b15ccb12bc6,
userName: 'frfrf',
email: 'anartoflijkjk67g6#gmail.com',
password: '$2b$10$NC5CXa3lXK4Cl1.W3c3nae.YrJvvhum//YSYskXkKKiDULeJdvZoO',
avatar: 'https://www.flaticon.com/svg/static/icons/svg/667/667378.svg',
status: 'USER',
moneyAmount: 0,
__v: 2
}
How to find an order by id of a user with a specific email, and replace his orderStatus with "Paid"?
How can I fix it?
I kind of did as in the documentation
if you have orders._id, with update() you can do what you want, so just try like this:
db.collection.update({
"orders._id": "602bc4c1a7fe3222c48b4efc",
"email": "anartoflijkjk67g6#gmail.com"
},
{
$set: {
"orders.$.totalOrderValue": 12345
}
})
mongoplayground
I have data formatted like so:
{
id: "59b47f582c981415e24ffaf6",
userName: "userName",
email: "email",
albums: [
{
_id: "59b4895b68697316e517ae2b",
timestamp: "2017-09-10T00:37:47.409Z",
images: [
"https://bjnsjbnsdrjnbvolsdjb.png"
],
description: "description",
name: "name"
},
}
I am trying to use $unwind to get a nice list of just the images. The closest I have gotten is
{
albums: {
images: [ ]
}
},
{
albums: {
images: [
"https://bjnsjbnsdrjnbvolsdjb.png",
"https://bjnsjbnsdrjnbvolsdjb.png"
]
}
},
That was using my query like so:
Profile.aggregate( [
{$project: {"albums.images": 1, _id: 0}},
{$unwind:"$albums"}
], function(err, images){
if (err){
reject(err)
return
}
resolve(images)
})
I thought I could just use {$unwind:"album.images"} but it gives me one empty array. Is there a way to write the query so it just returns a list of images?
I am new to elasticsearch, just started to try out utilize the elasticsearch to do fulltext search on nodejs. Currently I have a problem to find out the count the number of item of the nested field. For example suppose this is my data:
{
user1: {
movies: [
{
title: 'eat'
},
{
title: 'drink'
}
],
books: [
{
author: 'apple'
}
]
},
user2: {
movies: [
{
title: 'jump'
},
{
title: 'punch'
},
{
title: 'sleep'
},
{
title: 'eat'
}
],
books: [
{
author: 'orange'
}
]
}
}
how to do a simple count of how many movies does user1 or user2 have?(2 and 4 in this case).
If it turns out to be surprisingly difficult, I could still fallback to store that number somewhere else.
let users = {
user1: {
movies: [
{
title: 'eat'
},
{
title: 'drink'
}
],
books: [
{
author: 'apple'
}
]
},
user2: {
movies: [
{
title: 'jump'
},
{
title: 'punch'
},
{
title: 'sleep'
},
{
title: 'eat'
}
],
books: [
{
author: 'orange'
}
]
}
}
console.log(`User1 count: ${users.user1.movies.length}`);
console.log(`User2 count: ${users.user2.movies.length}`);
I am newbie in MEANJS and i have a problem i.e, there are collection called employee and have multiple documents with their boss field. Now i want get all employees with their lower level.
For example:-
1) {_id:ObjectId('587dcd3edca5f235f862fdfd'), name:'John'} //he doesn't have boss
2) {_id:ObjectId('587dcd3edca5f235f86dddew'), name: 'Jimmy', 'boss': ObjectId('587dcd3edca5f235f862fdfd')} //john is boss
3) {_id:ObjectId('587dcd3edca5f235f863ew'), name: 'David', 'boss': ObjectId('587dcd3edca5f235f86dddew')} //john,Jimmy are bosses
4) {_id:ObjectId('587dcd3edca5f235f86qwa'), name: 'Dyan', 'boss': ObjectId('587dcd3edca5f235f86dddew')} //john,Jimmy,David are bosses
5) {_id:ObjectId('587dcd3edca5f235f8ew32'), name:'Jack', 'boss': ObjectId('587dcd3edca5f235f862fdfd')} //john is boss
6) {_id:ObjectId('587dcd3edca5f2wsw23rlot'), name: 'Loren', 'boss':ObjectId('587dcd3edca5f235f8ew32')} //john,Jack is boss
If we take
Jonh then output will ['Jimmy','Jack','David','Dyan','Loren']
Jack then output will ['Loren']
Here is my try code:-
getBosses(user._id)
function getBosses(id){
User.find({boss:id})
.exec(function(err,users){
if(err)
return console.log(err);
//How handle here 'users' array
//for something getBosses call recursively
})
}
As far as I understood you need to find all subordinates of that people. I think the best way to do it is using $graphLookup.
db.bosses.insertMany([
{ _id: "587dcd3edca5f235f862fdfd", name: "John" },
{
_id: "587dcd3edca5f235f86dddew",
name: "Jimmy",
boss: "587dcd3edca5f235f862fdfd",
},
{
_id: "587dcd3edca5f235f863ew",
name: "David",
boss: "587dcd3edca5f235f86dddew",
},
{
_id: "587dcd3edca5f235f86qwa",
name: "Dyan",
boss: "587dcd3edca5f235f86dddew",
},
{
_id: "587dcd3edca5f235f8ew32",
name: "Jack",
boss: "587dcd3edca5f235f862fdfd",
},
{
_id: "587dcd3edca5f2wsw23rlot",
name: "Loren",
boss: "587dcd3edca5f235f8ew32",
},
]);
db.bosses.aggregate([
{
$graphLookup: {
from: "bosses",
startWith: "$_id",
connectFromField: "_id",
connectToField: "boss",
as: "subordinates",
},
},
{
$project: {
_id: false,
name: true,
subordinates: {
$reduce: {
input: "$subordinates",
initialValue: "",
in: { $concat: ["$$value", ", ", "$$this.name"] },
},
},
},
},
{
$project: {
name: true,
subordinates: { $substrBytes: ["$subordinates", 2, -1] },
},
},
]);
The result of the last one is:
[
{ name: 'John', subordinates: 'David, Dyan, Loren, Jack, Jimmy' },
{ name: 'Jimmy', subordinates: 'David, Dyan' },
{ name: 'David', subordinates: '' },
{ name: 'Dyan', subordinates: '' },
{ name: 'Jack', subordinates: 'Loren' },
{ name: 'Loren', subordinates: '' }
]
The most important thing is $graphLookup stage of the aggregate pipeline. Last two $project stages is just response formatting - return only name and subordinates as string field with comma separated names.
To get data for a specific person you can use $match stage before $graphLookup like that:
db.bosses.aggregate([
{ $match: { name: "John" } },
{
$graphLookup: ...