Find returns object on child element - mongodb

I'm trying to find all the fruit in my database where the colour is not red however when I run the find command below it returns [object]. What am I doing wrong
database: mongoDB
"fruit": {
"color": [
"red"
]
}
Path: server.js
var fruit = fruit.find({
"fruit.color": { $nin: [ red ] },
}).fetch();
If I console log on the server it retuns the following.
console.log(fruit);
{ color: [Object] } } ]

Your find returns an array of objects, that's why you get the [object] result. You have to iterate the result. Like:
var fruits = fruit.find({
"fruit.color": { $nin: [ red ] },
}).fetch();
fruits.forEach(function (afruit) {
console.log(afruit.color);
});

Related

In mongodb how do I replace array field with null value to an empty array

I want to replace an array field in document that has value of null to an empty array []. I tried this query but it's not working. Please help.
Basically I want testArray: null to be testArray: []
db.myTestCollection.aggregate( { "_id": ObjectId('1120191011212112') },
[ { $set: { testArray: { $ifNull: [ { $concatArrays: [ "$testArray", [] ] } ] } } }
])
Looks like you mostly have a syntax error. But you can also move the $ifNull logic into the filter predicate as well so that no update is considered/applied if the existing testArray field isn't already null. So:
db.collection.update({
_id: 1,
"testArray": null
},
[
{
$set: {
testArray: []
}
}
])
Working playground example here.

MongoDB: Can't update in nested arrays

I've been trying to modify a value in multiple arrays for a few arrays and I can't find documentation on how to do this.
My collection looks like this
"rates": [
{
"category": "Web",
"seniorityRates": [
{
"seniority": "junior",
"rate": 100
},
{
"seniority": "intermediate",
"rate": 135
},
{
"seniority": "senior",
"rate": 165
}
]
}
]
I'm just trying to modify "junior" to "beginner", this should be simple.
Thanks to these answers:
How can I update a multi level nested array in MongoDB?
MongoDB updating fields in nested array
I've manage to write that python code (pymongo), but it doesn't works...
result = my_coll.update_many({},
{
"$set":
{
"rates.$[].seniorityRates.$[j].seniority" : new
}
},
upsert=False,
array_filters= [
{
"j.seniority": old
}
]
)
The path 'rates' must exist in the document in order to apply array updates.
It correspond to this command that doesn't work either
db.projects.updateMany({},
{
$set:
{
"rates.$[].seniorityRates.$[j].seniority" : "debutant"
}
},
{ arrayFilters = [
{
"j.seniority": "junior"
}
]
}
)
clone(t={}){const r=t.loc||{};return e({loc:new Position("line"in r?r.line:this.loc.line,"column"in r?r.column:......)} could not be cloned
What am I doing wrong ?
Any help would be very appreciated
The other option could be Sample
db.collection.update({},
{
$set: {
"rates.$[].seniorityRates.$[j].seniority": "debutant"
}
},
{
arrayFilters: [
{
"j.rate": { //As per your data, you can apply the condition o rate field to modify the level
$lte: 100
}
}
]
})
Or
The actual query should work Sample
db.collection.update({},
{
$set: {
"rates.$[].seniorityRates.$[j].seniority": "debutant"
}
},
{
arrayFilters: [
{
"j.seniority": "junior"
}
]
})
The same should work in python, a sample question
So I was just dumb here, I inverted two parameters so I didn't have the correct collection in the python code...
Thanks Gibbs for pointing out where the mistake was in the mongo command.
I will not delete this post as it can help other to know how to do this kind of queries.

How to find the records from the object array of object in MongoDB

My mongodb, collection name: person
[
{
name:"John",
pens:[
{color:"blue", price:1},
{color:"black",price:2},
{color:"black", price:3},
{color:"red", price:2}
]
},
{
name:"Mary",
pens:[
{color:"green", price:3},
{color:"black",price:2},
{color:"blue", price:1},
{color:"red", price:2}
]
},
{
name:"Tom",
pens:[
{color:"black", price:1},
{color:"black",price:4},
{color:"blue", price:1},
{color:"green", price:3}
]
}
]
First question:
I would like to find out all black pens of "John" and hope the result is like this
[
{color:"black", price:2},
{color:"black, price:3"}
]
However, my query
db.person.find({name:"John"},{pens:{$elemMatch:{color:"black"}}})
It only shows the first record. How do I get the records in the subarray?
[
{color:black,price:2}
]
The second question:
I would like to find out how many black pens John has.
db.person.count({name:"John"},{pens:{$elemMatch:{color:"black"}}})
It shows 1 but the correct number is 2.
How do I get the correct count in the subarray?
The $elemMatch operator project the first matching element from an array based on a condition.
https://docs.mongodb.com/manual/reference/operator/projection/elemMatch/
Workaround: Perform MongoDB aggregation. With $filter operator we take black color pens.
db.person.aggregate([
{
$match: {
name: "John"
}
},
{
$addFields: {
pens: {
$filter: {
input: "$pens",
as: "pens",
cond: {
$eq: [
"$$pens.color",
"black"
]
}
}
}
}
},
{
$unwind: "$pens"
},
{
$replaceWith: "$pens"
}
])
MongoPlayground | Count black pens

Convert the mongoose find() query result into flat array

Upon the mongoose find() query the result i am getting is:
[
{
"services":[
{
"location":[
17.4374614,
78.4482878
]
},
{
"location":[
17.4020637,
78.48400519999996
]
},
{
"location":[
17.387031788259197,
78.47838450137715
]
}
]
}
]
Is there any way to extract the output in such a way that i want an array of only location values such as:-
[
'17.4374614',
'78.4482878',
'17.4020637',
'78.48400519999996',
'17.387031788259197',
'78.47838450137715'
]
Edit: I am aware that map method does the job, but i am not able to find a workaround of implementing the map method for the above query.
My schema:
var serviceSchema = new mongoose.Schema({
location:[{type: Number}]
})
I used for-of loop and map function to achieve the result you need
var your_output =[
{
"services":[
{
"location":[
17.4374614,
78.4482878
]
},
{
"location":[
17.4020637,
78.48400519999996
]
},
{
"location":[
17.387031788259197,
78.47838450137715
]
}
]
}
]
var location_array = []
for (var services of output[0].services) {
for(var loc of services.location){
location_array.push(loc)
}
}
location_array.map(String)

query 2-level array in mongodb

in MongoDB, I have many documents in 2-level array as below:
{
_id:1,
"toPerson": [
[
{
"userid": "test1"
},
{
"userid": "test2"
}
],
[
{
"userid": "test10"
},
{
"userid": "test11"
}
]
]
}
.....
{
_id:99,
"toPerson": [
[
{
"userid": "test2"
},
{
"userid": "test3"
}
],
[
{
"userid": "test100"
},
{
"userid": "test101"
}
]
]
}
Question is how to query all documents that have userid say test2 ?
Have tried:
col.find({'toPerson.userid':'test2'})
it's return nothing. also I have tried using aggregate but found maybe it's not the right direction.
Anyone can help with this?
UPDATE 1
Just read this post
Retrieve only the queried element in an object array in MongoDB collection
but it's different
Structure different: is {field:[ [{ }], [{ }], .... ]}, not { field:[ {}, {} ] }
I want to keep all returned documents structure untouched, $unwind(make toPerson to be 1-level array) or $$PRUNE(remove some fields) will change the structure returned.
UPDATE 2
What I want is to get following result in ONE statement:
col.find({ 'toPerson.0.userid':'test2' })
+ col.find({ 'toPerson.1.userid':'test2' })
+ ... ...
Is there any precise counterpart statement of above results combined together ?
You can query nested arrays like this using two levels of $elemMatch:
db.test.find({toPerson: {$elemMatch: {$elemMatch: {userid: 'test2'}}}})
The outer $elemMatch says match an array element of toPerson where the value passes the inner array $elemMatch test of an element matching {userid: 'test'}.