js add object to object with $or and get [object] - javascript

I try to generate an object with {$or: [{object1}, {object2},...]} to fire a query to mongo, but I always get [object] after assigning to $or. Can somebody help me and tell me what I´m doing wrong. I tried it with creating an own array for the $or[], with a for-loop and so on - always the same. Some ideas?
if(req.body.sicDiv) {
co_sicDiv = {
$in: sicDiv.split(',')
};
query = Object.assign({co_sicDiv: co_sicDiv}, query);
//works fine, I get: { co_sicDiv: { '$in': [ 'C' ] }
}
if(req.body.sicMajor) {
if (sicDiv){
co_sicMaj = {
$in: sicMaj.split(',')
};
console.log('co_sicMaj: ', co_sicMaj);
sicMajO =Object.assign(
{'co_sicDiv': co_sicDiv},
{'co_sicMaj' : co_sicMaj}
);
console.log('SicMajO: ', sicMajO);
//Works fine, I get: SicMajO: { co_sicDiv: { '$in': [ 'C' ] }, co_sicMaj: { '$in': [ '15', '16' ] } }
sicMajOR =Object.assign({$or: [
{'co_sicDiv': co_sicDiv},
{'co_sicMaj' : co_sicMaj}
]}
);
console.log('SicMajOR: ', sicMajOR);
//Doesn´t work, I get: SicMajOR: { '$or': [ { co_sicDiv: [Object] }, { co_sicMaj: [Object] } ] }

Related

how to catch mongo change streams when one key in object gets updated

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

Problem with countDocuments Mongoose: its not actually waiting for the callback function to execute

I've a problem with a Mongoose backend. i guess its an asynchronous problem. Can someone try to explain me how countDocuments works?
albumFields.features = [];
for await (const feature of features) {
await Artist.countDocuments({ _id: feature._id }, (err, count) => {
if (count > 0) {
albumFields.features.push({ _id: feature._id });
}
console.log('artist.count', albumFields.features);
});
console.log('features.forEach', albumFields.features);
}
console.log('!!!', albumFields.features);
the output im getting is:
artist.count [ { _id: '5ec09f9c99339f3ad85973c0' } ]
features.forEach [ { _id: '5ec09f9c99339f3ad85973c0' } ]
features.forEach [ { _id: '5ec09f9c99339f3ad85973c0' } ]
!!! [ { _id: '5ec09f9c99339f3ad85973c0' } ]
artist.count [ { _id: '5ec09f9c99339f3ad85973c0' },
{ _id: '5ec09fb199339f3ad85973c4' } ]
The output i would expect is:
artist.count [ { _id: '5ec09f9c99339f3ad85973c0' } ]
features.forEach [ { _id: '5ec09f9c99339f3ad85973c0' } ]
artist.count [ { _id: '5ec09f9c99339f3ad85973c0' },
{ _id: '5ec09fb199339f3ad85973c4' } ]
features.forEach [ { _id: '5ec09f9c99339f3ad85973c0' },
{ _id: '5ec09fb199339f3ad85973c4' } ]
!!! [ { _id: '5ec09f9c99339f3ad85973c0' },
{ _id: '5ec09fb199339f3ad85973c4' } ]
So the problem is countDocuments() will return a promise only if there is no call back function. In our case we created the callback which gets the number of documents matching the filter.
I am not sure why the code executed the way it did so maybe someone can explain but I did manage to solve the problem.
let arraytest = [];
for (const feature of features) {
await Artist.countDocuments({ _id: feature._id }).then((count) => {
if (count > 0) {
albumFields.features = [
...albumFields.features,
{ _id: feature._id },
];
}
});
}
For anyone else who runs into the same problem, there was a link on the mongoose documentation which is easy to miss.
https://mongodb.github.io/node-mongodb-native/3.1/api/Collection.html#countDocuments

(mongoDB) find with empty or null values

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

How to I get the values of the keys in this javascript object inside the arrays?

I need the value for the key country_code and language_code.
I have tried
sourceLanguageArray[0].$.country_code;
sourceLanguageArray[0].$.language_code;
I get the error:
console.log(sourceLanguageArray[0].$.country_code);
^
ReferenceError: sourceLanguageArray is not defined
This is how the code and console logs of the data structure looks like:
source_language (includes country_code and language_code)
const sourceLanguageArray = _.map(ontomlClass, 'source_language');
console.log(sourceLanguageArray);
// => [ [ { '$': [Object] } ], [ { '$': [Object] } ],[ { '$': [Object] } ] ]
// => [ { '$': [Object] } ]
console.log(sourceLanguageArray[0]);
// => [ { '$': { country_code: 'US', language_code: 'en' } } ]
var sourceLanguageArray = [[ { '$': { country_code: 'US', language_code: 'en' } } ]];
console.log("sourceLanguageArray[0]:", sourceLanguageArray[0]);
console.log("country code:", sourceLanguageArray[0][0].$.country_code);
console.log("language code:", sourceLanguageArray[0][0].$.language_code);
try this:
sourceLanguageArray.forEach(function(item){
console.log(item[0]['$'][country_code]);
console.log(item[0]['$'][language_code]);
})

How to get the name of the most "root" key?

I have a js object in NodeJs application:
> req.body
{ my_root_key: { some_key2: [ [Object] ], some_key3: [ [Object] ] } }
How can I obtain the name of the most base key, in this case "my_root_key"?
Try this:
var data = { my_root_key: { some_key2: [ [Object] ], some_key3: [ [Object] ] } }
console.log(Object.keys(data)[0]);

Categories

Resources