Mongodb: can I compare if value in one field is contained in another field - node.js

Suppose I have a collection a called collection_a that contains a lookup to a collection b called collection_b. If the collection contains a field called primary_color and the lookup contains a field called available_colors. How can I compare primary_color to available_colors to see if the current value for primary_color is contained in the available_colors list?
I tried the following but it did not work in a aggregate match,
{'primary_color': {'$in': '$collection_b.available_colors'}}.

It is not possible to refer another collection in $match stage.
You have to use $lookup or populate in mongoose.
db.collectiona.aggregate([
{"$lookup":{
"from":collectionb,
"localField":"primary_color",
"foreignField":"available_colors",
"as":"matches"
}},
{"$match":{"matches.0":{"$exists":true}}}
])
https://mongoplayground.net/p/bkQzZcrP0aJ

Related

How to query field exist some document in firebase

I using firebase, nodejs and i have a question how to query field exist some document.
Example :
Collections : users => document : A with field {
....
is_correct: true
}
document : B with field {
.....
}
In my above example , i have two document in collection users. On document A i have field is_correct: true and on document B field is_correct not exist.
My collection users about 15.000 document and it have 50 document contain field is_correct: true
When i write code look like :
await firestore.collection('users').where('is_correct', '==', true).get();
it can get correct me 50 document. But i don't understand it can using index on field is_correct or not ? And it can query best performance ? I understand firebase can't get document if field undefined. It impart in case ? Please help ? Thanks you
For a simple query like
firestore.collection('users').where('is_correct', '==', true)
you don't need to configure any index, Firestore does it automatically.
As you mentioned, only documents where the given field exists can match the query.
And this is the case also for Not-equal (!=) and not-in queries: they exclude documents where the given field does not exist, as explained in the documentation.
Also, note that a field exists when it's set to any value, including an empty string (""), null, and NaN (not a number).
So, in conclusion, if you want to query for documents where is_correct is not true, you need to create this field in these documents with a value different than true.

Get all documents whose property equals one of the elements in an array

I have a Post model that has a publisher property defined in its schema (I'm using Mongoose). The publisher property is a string that refers to a publisher's name.
I also have an array called sourceNames that holds all the different publisher names. I want to query my database for ALL the posts whose publisher matches any one of the array elements in sourceName. My current query looks like this:
const query = postModel
.find({ publisher: { $all: sourceNames } })
.limit(limit)
.skip(startIndex);
My query isn't returning anything when I exec it. Does anyone know if what I'm trying to do is possible in a single query (Rather than loop over sourceNames and make a query for each individual element?
Short
Just replace $all with $in
Expl
$all is trying to match an array with all elements in your array.
$in instead, tries to match a string or array with one in the array.

Increment nested field value in mongodb if exists or create nested fields

I need to increment the multi level nested field value if it exists or create the complete nested field Object structure.
Structure of my document
Doc1 {
_id:ObjectId(),
myField: {
nested:{
x: 5,
y: 10,
z: 20
}
}
}
Goal Explanation: I need a way to write a single query:
If myField exists: Increment the value of my nested field
myField.nested.x by 10.
If myField does not exists: Create the below field with initial values same as given in the Doc1.
Attempt and explanation:
db.collection('collectionName').findOneAndUpdate(
{_id:"userId","myField" : { $exists : true }},
{$inc:{'myField.nested.x':10}
})
This way, I can increment the nested field if it exists but in case of non existence I cannot set myField as same as Doc1.
Although, I can use another query after response in my NodeJs callback to achieve my required behaviour. But I need some elegant solution in a single query.
I am using MongoDB version 4.0.4, Thanks in Advance.
Try this query
If the field does not exist, $inc creates the field and sets the field to the specified value.
db.collection('collectionName').findOneAndUpdate({_id:"userId"},
{$inc:{'myField.nested.x':10}
})

How to Match the string from collection after lookup with many collection using mongodb

Here My query
model.db.aggregate([{$lookup: {from: 'orders', localField: 'prod_id',
foreignField: '_id', as: 'Col'}},{$match:{$text:
{$search:'Sale'}}}).exec((err,data) => {console.log(data);}]);
but error showing "$match with $text is only allowed as the first pipeline !!"
I just want to lookup many collection then only I have to match'Search' in all the data what we joined(lookup) before.
mongoDb version: 4.0
Anybody have an idea ? need Help !
Thanks !!
These all are my Example collections:
collection 1 ->
organization ={'_id':ObjectId("5b110a7b84a0442030a1e9cf"),'Org_name':'dhoni institute','Estd':'1945'}
collection 2 -> players= {'_id':ObjectId("45110a7b84a3542030a1e9cf"),'_name':'Ms dhoni','Org_id' = ObjectId("5b110a7b84a0442030a1e9cf") }
I am searching the text string 'dhoni' in Db..then I want all the documents which contains word 'dhoni' from these collections.
How to do ?
db.players.aggregate([{$match:{$text:{$search:'dhoni'}}},
{
$lookup{from:'organization',localField:'_id',foreignField:'Org_id',as:'org'}
}
]).exec((err,data) => {}
this is my code It only matches the string from 'players' collection .I need matched 'players' collection documents as well as 'Organization' collection documents.
I cannot create new collection because after loopup data may be a huge data so
I cannot inserting new large data every time search
How to match the string after lookup ?
As explained in official mongodb documentation,
$text performs a text search on the content of the fields indexed with a text index.
But indexes are reachable only by the first stage of an aggregation query. That's the reason of your error message.
The only way i see for you to use $text/$search is to perform your aggregation (without match stage), adding an $out stage to output to a new collection, create a text index on that collection, and perform your find query with $text/$search criteria.
Hope it helps.

Sort by a array element (document) field - MongoDB/Mongoose

This is the concerned part from the schema
`
var CandidateSchema = new Schema({
calculateScore:[{
jobname:{type:Schema.ObjectId,ref: 'Job'}
,Score:{type:Number,default:0}
}]
})
`
A candidate can apply to multiple jobs and get scored differently for different jobs. I want to sort the candidates depending on the specific job's Score. Any Idea?
Assuming the variable objectId holds the ObjectId of the referred Job, you can aggregate the records to get the records sorted by the score of that particular Job.
Since the stage operator $project does not support the $elemeMatch operation, we cannot use it to directly get the Job sub document that we want and sort based on it.
$project a separate field named temp_score to have a copy of the original calculateScore array.
$redact other sub documents from calculateScore other than whose jobname contains the
id we are looking for. Now calculateScore will contain only one
element in the array, i.e the element whose jobname is the id
that we have specified.
Based on this sub document's score sort the records in descending
order.
Once the sorting is done, project our original calculatescore
field, which is in temp_score.
The code:
var objectId = ObjectId("ObjectId of the referred Job"); // Needs to be fetched
// from the Job collection.
model.aggregate(
{$project:{"temp_score":{"level":{$literal:1},
"calculateScore":"$calculateScore"},
"calculateScore":1}},
{$redact:{$cond:[
{$and:[
{$eq:[{$ifNull:["$jobname",objectId]},objectId]},
{$ne:["$level",1]}
]
},
"$$DESCEND",
{$cond:[{$eq:["$level",1]},
"$$KEEP","$$PRUNE"]}]}},
{$sort:{"calculateScore.Score":-1}},
{$project:{"_id":1,
"calculateScore":"$temp_score.calculateScore"}},
function(err,res)
{
console.log(res);
}
);

Resources