MongoDB find value in array that does not exist in database - javascript

Here I have an array. Some of the values listed below already exist in MongoDB, but I need the values that do not currently exist in the database
ex: -
Values currently in the database
[
{"id":100},
{"id":500},
{"id":606},
{"id":800}
]
the value I have
let x = [100,300,400,500,606,800];
I need the output to consist of the following values:
300,400
These values need to be added because they do not already exist in the database

dbo.collection.aggregate([{
$group: {
_id: null,
names: {
"$addToSet": "$uid"
}
}
},
{
"$replaceRoot": {
"newRoot": {
results: {
$filter: {
input: x,
as: "datum",
cond: {
$not: {
"$setIsSubset": [
[
"$$datum"
],
"$names"
]
}
}
}
}
}
}
}
]).toArray(function(err, result) {
console.log(result);
})

Related

MongoDB hash object projection

If there is an object with unknown keys:
{
data: {
someObjectIdStringThatCantBePutInProjection: {
dontReturn: 123,
return: 321
},
someOtherObjectIdStringThatCantBePutInProjection: {
dontReturn: 1234,
return: 4321
}
}
}
And I want MongoDB to return only return property of the objects of the objects, what would the projection look like?
For example a projection
{
data: { **allProperties**: { return: 1 } }
}
should return:
{
data: {
someObjectIdStringThatCantBePutInProjection: {
return: 321
},
someOtherObjectIdStringThatCantBePutInProjection: {
return: 4321
}
}
}
Using dynamic values as field names is considered an anti-pattern and introduces unnecessary complexity to queries. Nevertheless, you can convert the data object to an array of k-v tuples by $objectToArray. Use $map to get only the return field you need. Finally, use $arrayToObject to revert back to original form.
db.collection.aggregate([
{
"$set": {
"data": {
"$map": {
"input": {
"$objectToArray": "$data"
},
"as": "d",
"in": {
k: "$$d.k",
v: {
return: "$$d.v.return"
}
}
}
}
}
},
{
"$set": {
"data": {
"$arrayToObject": "$data"
}
}
}
])
Mongo Playground

Elastic Search check if object has a key x and matches some crieteria

So I am working on a generic Elastic search method. I can generate queries well but I need to find a way to check if a document has property x, it must match a value y
something like;
{
index: 'any-index',
query {
bool: { must: [...queries] },
// if has property companyId, only return objects with companyId == 4
}
}
I believe that a filter with exists-query can be a solution.
{
"query": {
"bool": {
"filter": [
{
"exists": {
"field": "field_name"
}
}
],
"must": [
{
"match": {
"field_name": "xpto"
}
}
]
}
}
}

Return variable from database find instead of array

I need to pull two values out of my mongoDB database and right now the code is returning an array. How do I get:
totalGuests
attendedGuests
out of the query and stored in variables so I can display them on the client?
module.exports.showEvent = async(req, res,) => {
const event = await Event.findById(req.params.id).populate('artist');
if (!event) {
req.flash('error', 'Cannot find that Event');
return res.redirect('/events');
}
res.render('events/show', { event });
const { guest_id } = req.cookies;
const lookUp = Event.collection.find({ _id: req.params.id},
{
_id: 1,
name: 1,
guests: 1,
totalGuests: {
$size: "$guests"
},
attendedGuests: {
$size: {
"$filter": {
input: "$guests",
cond: {
$eq: [
"$$this.attended",
"Y"
]
}
}
}
}
});
console.log(lookUp);

Count number of fields that match in an Array of Object in mongodb

What I have
I have a DB in MongoDB like this:
{
"_id": {
"$oid": "60ba531acbfed3545c51a49e"
},
"email": "shaswat.dharaiya#gmail.com",
"Formats": [{
"format": "AST-QC",
}],
"Series": [{
"seq": "AST-QC - 1",
},
{
"seq": "AST-QC - 2",
},
{
"seq": "AST-QD - 1",
}]
}
I am successfully getting the data from the Formats array using this query:
const pipeline = [
{ $match: { "email": email } },
{ $unwind: "$Formats" },
]
const res = await colc.aggregate(pipeline)
What I want
Along with the data in the Formats array, I need the count of every format that is used by seq in Series array.
I am certain that it can be done using $addFields, Something like this.
const pipeline = [
{ $match: { "email": email } },
{ $unwind: "$Formats" },
{ $addFields: {"Formats.count": 0} }
]
const res = await colc.aggregate(pipeline)
But I am not sure as to how.
I don't want to call another query using .count()
$filter to iterate loop of Series array
$regexMatch to search format in seb
$size to get total elements in filtered result
const pipeline = [
{ $match: { email: email } },
{ $unwind: "$Formats" },
{
$addFields: {
"Formats.count": {
$size: {
$filter: {
input: "$Series",
cond: {
$regexMatch: {
input: "$$this.seq",
regex: "$Formats.format"
}
}
}
}
}
}
}
]
Playground

Joi - validate property against value in array of objects

Im trying to validate a value of a particular property in a payload against a defined array of objects.
for example
payload
{
a:[1, 2]
}
the value of "a" must be a one of the id defined in a array of objects (multiple values allowed)
[
{
"id":1,
"share":{
"x":100,
"y":0,
"z":0
}
},
{
"id":2,
"share":{
"x":90,
"y":0,
"z":10
}
}
....and so on
]
Could you please help advising if this can be achieved with Joi?
Thanks, Gowrish
Joi's array.validate() with items should do what you're looking for.
const Joi = require("joi")
const input = { a: [ 1, 2 ] }
const objects = [{ id: 1 }, { id: 2 }, { id: 3 }]
const schema = {
a: Joi.array().items(Joi.any().valid(objects.map(o => o.id)))
}
const result = Joi.validate(input, schema, (err, result) => {
if (err) {
console.error('error:', err)
return
}
console.log('result:', result)
})

Categories