how to delete the "extras" with "id_extra = 8523" of the "book" "id_book = 8522" of that particular user?, I currently use mongoosejs but I didn't succeed, I tried many stuffs, but whatever I tried was working just till the first level of nested doc.
{
"_id":{
"$oid":"5e32fce08919b53ad66cf694"
},
"user_id":{
"$numberInt":"258787"
},
"username":"daaaa",
"firstname":"davide",
"api_key":"7b031c21edf1237c554867622ad1154f",
"books":[
{
"_id":{
"$oid":"5e356323a0ef6319ebb60162"
},
"id_book":{
"$numberInt":"8522"
},
"blob_annotation":null,
"extra_id":{
"$numberInt":"995176"
},
"extras":[
{
"_id":{
"$oid":"5e356324a0ef6319ebb60163"
},
"id_extra":{
"$numberInt":"8523"
},
"type":"gallery_audio",
"label":"Inverno a Boscodirovo"
},
{
"_id":{
"$oid":"5e356324a0ef6319ebb60164"
},
"id_extra":{
"$numberInt":"8524"
},
"type":"gallery_audio",
"label":"Storia di Primavera"
}
],
"raccolte":[
]
}
],
}
Try using elemMatch in conjunction with $:
db.books.update(
{
books: {
$elemMatch: {
"id_book": 8522,
"extras.id_extra": 8523
}
},
user_id: 258787
},
{
$pull: {
"books.$.extras": {
"id_extra": 8523
}
}
}
)
You may do this trick: Filter "extras" with "id_extra = 8523" of the "book" "id_book = 8522" and save documents again in MongoDB
db.collection.aggregate([
{
$match: {
"books.id_book": 8522
}
},
{
$addFields: {
"books": {
$reduce: {
input: "$books",
initialValue: [],
in: {
$concatArrays: [
"$$value",
[
{
_id: "$$this._id",
id_book: "$$this.id_book",
blob_annotation: "$$this.blob_annotation",
extra_id: "$$this.extra_id",
raccolte: "$$this.raccolte",
extras: {
$filter: {
input: "$$this.extras",
cond: {
$ne: [
"$$this.id_extra",
8523
]
}
}
}
}
]
]
}
}
}
}
}
])
MongoPlayground
Related
I am using the mongo change stream to update some of my data in the cache. This is the Documentation i am following.
I want to know when one of the keys in my object gets updated.
Schema :- attributes: { position: { type: Number } },
How will I come to know when the position will get updated?
This is how my updateDescription object looks like after updation
updateDescription = {
updatedFields: { 'attributes.position': 1, randomKey: '1234'},
removedFields: []
}
Tried this and its not working
Collection.watch(
[
{
$match: {
$and: [
{ operationType: { $in: ['update'] } },
{
$or: [
{ 'updateDescription.updatedFields[attributes.position]': { $exists: true } },
],
},
],
},
},
],
{ fullDocument: 'updateLookup' },
);
I was able to fix it like this,
const streamUpdates = <CollectionName>.watch(
[
{
$project:
{
'updateDescription.updatedFields': { $objectToArray: '$updateDescription.updatedFields' },
fullDocument: 1,
operationType: 1,
},
},
{
$match: {
$and: [
{ operationType: 'update' },
{
'updateDescription.updatedFields.k': {
$in: [
'attributes.position',
],
},
},
],
},
},
],
{ fullDocument: 'updateLookup' },
);
and then do something with the stream
streamUpdates.on('change', async (next) => {
//your logic
});
Read more here MongoDB
It's my line of code you see below is not working! It always returns an empty array value.
Please help me!
That's working!
const data = await NumbersModel.aggregate([
{
$project: {
Datas: {
$filter: {
input: "$Datas",
as: "data",
cond: { $gte: [ "$$data.time", lastdata ] }
}
}
}
])
That's not working!
const data = await NumbersModel.aggregate([
{
$project: {
Datas: {
$filter: {
input: "$Datas",
as: "data",
cond: {
$and: [
{ $gte: [ "$$data.time", lastdata ], },
{ $eq: [ "$$data.number", req.query.number ] }
]
}
}
}
}
}
])
It's working :)
const data = await NumbersModel.find({ "Datas.time": { $gte: lastdata }, Number: req.query.number })
Schema
[
{
_id:"doc1",
type:"SR",
title:"...",
description:"...",
author:"5",
posts:[
{
author:"1",
title:"..."
},
{
author:"2",
title:"..."
},
{
author:"1",
title:"..."
}
]
},
{
_id:"doc2",
type:"SA",
title:"...",
description:"...",
posts:[],
author:"5"
}
]
Every Document will have type either SA or SR. If type is SA then posts will be an empty array, otherwise it'll non empty.
Now, i want to get document and array elements based on certain conditions.
if type is SA and authorId=5 then return the entire document.
if type is SR then return the elements of posts where authorId=1
When type is SA then i would like to get title,description,.. of the document otherwise get the posts by filter.
My Query
Using mongoose
Blog.find({
$or: [
{
$and: [
{ type: "SA" },
{ authorId:"5" }
]
},
{
"posts.authorId": "1"
}
]
}, {
posts: {
$filter: {
input: "$posts",
as: "post",
cond: {
$eq: ["$$post.authorId", "1"]
}
}
}
})
.then(posts => {
console.log(posts)
})
.catch(err => {
console.log(err);
})
Returned document
[
{
_id:"doc1",
posts:[
{
author:"1",
title:"..."
},
{
author:"1",
title:"..."
}
]
},
{
_id:"doc2",
posts:[]
}
]
How can i include other attribute of doc2?
Data:
Is there any way to access all of these "lineText" fields from the collection in MongoDB through a single query?
Try this
db.collectionName.aggregate([
{ $unwind: "$text" },
{ $unwind: "$text.paragraphs" },
{
$group: {
_id: null,
result: {
$push: {
$arrayElemAt: ["$text.paragraphs.lineText", 0]
}
}
}
},
{
$project: {
result: {
$reduce: {
input: "$result",
initialValue: "",
in: { "$concat": ["$$value", "$$this"] }
}
}
}
}
]);
how to make a mongodb collection find (db.collection.find) with empty values?
currently i have:
function test(s) {
if (!s) {
return null;
} else {
return s;
}
}
var content = {
date: {
from: '2017-10-15',
to: '2017-11-15'
},
'name': 'some text', //this can be null or empty
'text': 'some other text' //this can be null or empty
}
col.find({
"date": {
$gte: new Date(content.date.from),
$lte: new Date(content.date.to)
},
"name": {
$ne: {
$type: null
},
$eq: test(content.name)
},
"text": {
$ne: {
$type: null
},
$eq: test(content.text)
},
}).toArray((err, items) => {
console.log(items)
});
but it returns an empty array, because "name" or "text" is null / an empty string,
i want that it query only the values that have something specified or ignore it (like content.name is something in it or its empty)
how do i get it? i already searched ... but didnt found something
thanks!
( already testet mongoDB : multi value field search ignoring null fields)
Versions:
Node: 8.9.0
(npm) mongodb: 2.2.33
mongodb: 3.4
Try using $and, $or operators. Something like.
col.find({
$and:[
{"date": {$gte: new Date(content.date.from),$lte: new Date(content.date.to)}},
{"$or":[{"name": {$ne: {$type: null}}},{"name":test(content.name)}]},
{"$or":[{"text": {$ne: {$type: null}}},{"text":test(content.text)}]}
]
}).toArray((err, items) => {
console.log(items)
});
col.find({
$and: [
{
$and: [
{
"date": {
$gte: new Date(content.date.from)
}
},
{
"date": {
$lte: new Date(content.date.to)
}
},
]
},
{
$or: [
{ 'name': null },
{ 'name': content.name }
]
},
{
$or: [
{ 'text': null },
{ 'text': content.text }
]
}
]
})
Edited:
col.find({
$and: [
{
$and: [
{
"date": {
$gte: new Date(content.date.from)
}
},
{
"date": {
$lte: new Date(content.date.to)
}
},
]
},
{
$or: [
{ 'name': null },
{ 'name':'' }
{ 'name': content.name }
]
},
{
$or: [
{ 'text': null },
{ 'text': '' },
{ 'text': content.text }
]
}
]
})
null and empty is different, you need to add one more condition for empty string in query.
Logical Query Operators