How to compare two multiple fileds in document in mongodb - node.js

i have collection called "devices". this devices collection have two fields called as "devices" and "totalDeviceNeeds". totalDeviceNeeds have integer value. devices field contain array. I want to get all documents that totalDeviceNeeds > devices array size. How can i do that. I try lot of ways and didnt get correct. I try in nodejs.

Thank you all.
i just wrote query code or whatever called. here is this
db.collection.find({ $expr:{ $lt:[{$size:"$devices"}, "$totalDeviceNeeds"] } }).toArray();
in this $lt meaning less than operation
i used this post to do this.
https://www.mongodb.com/community/forums/t/is-there-a-way-to-query-array-fields-with-size-greater-than-some-specified-value/54597/2

Related

Multiple Inputs in ne mongoose method

I have users collection and I would like to get all users where status doesn't equal 'deleted' or 'pending'
I tried this
users.find().where('status').ne('deleted').where('status').ne('pending')
but it doesn't work.
I also tried this
users.find().where('status').ne(['deleted','pending'])
Also doesn't work.
How would I accomplish it?
I know it can be accomplished using a nested query string, but I want a way with the help of these query methods.
If you want to do multiple $ne then do
users.find({status: {$nin : ["deleted", "pending"]}})
https://docs.mongodb.com/manual/reference/operator/query/nin/

find all documents from mongodb collection with some attribute having value lie in an array

I want to find all documents in a collection where they have property like
Creator and i have an array which contains different values for this creator property and i want to of those documents where these different values in that array are the value of property creator in the document.
I tried by mapping the array and for each array value i tired to find document.
But due to its asynchronous nature i have to promise.all in order get that array of documents.
But when i passed that array to my react app from backend
It is showing error of incorrect react child class.....
You can achieve it using the $in operator from Mongo:
db.customers.find({creator: {$in: ["faizulhassan.a#caratlane.com", "sajid.s#caratlane.com"]}})
Where Customer is your collection name.
Hope this helps..
const answer = collectionName.find({creator: "what you want to find"});
if(!answer){
#do something
} else{
#do something
}

How to modify array single subdocument without loading that entire array in-memory?

I'm using Node.js v8.12.0, MongoDB v4.0.4 & Mongoose v5.3.1.
I want to update an embedded array subdocument without changing its position in array index. And without loading the entire array in memory because that array might get very big in future.
I spent a lot of time searching how to achieve this but without luck.
I've tried to use Mongo's $elemMatch to load the document with only single relevant array subdocument, but that wouldn't let me save the subdocument in any practical way.
I've also looked into Mongoose array set method, but for this you need to have subdocument array index, so this mean I need to load the entire array into a memory and then find subdocument index.
Is there any way to achieve what I want? Ideally via Mongoose abstractions, so all Mongoose middleware like validations, plugins, etc. kick in.
Actually found the answer right after submitting this question.
For anyone looking it up in future, you can use special $ operator in combination with $set. (I'm not sure if that makes use of mongoose middlewares, though. I need to do some testing around that).
Here's some code example, which queries some subdocument using _id, and then updates that subdocument property someProperty using $set which uses special operator $ that matches queried subdocument array position/index.
var doc = await SomeModel.findOneAndUpdate(
{'someArray._id': 'xxx'},
{'$set': {'someArray.$.someProperty': 'someValue'}},
);
It's still not 100% what I'm looking for, though. Because the returned doc still has full array of subdocuments (I assume that's still loaded into memory?), and it seems that I can't use $elemMatch in combination with $set.
In my case, further down the road, I'll probably redesign the database schema so these embedded subdocuments will be their own documents with just ObjectID reference to "parent" document.
Some resources:
https://docs.mongodb.com/manual/reference/operator/update/positional/
https://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate

Finding items by simpler ID's on MongooseJS

I'm playing with mongoose schemas. I have 3 items, each one with a corresponding ID field like this:
"_id": "508dcb79cb1c8ad910000001","
"_id": "508dcba389e2f32e11000002","
"_id": "508dcba389e2f32e11000003","
Is there any default way to process that big chunk of ID to get a cleaner one without having to set up custom id's numbers to just get the last numbers, corresponding the ID?
Or should I use a regex or something to be able to get them by id like this:
app.get('/fields/:id', function(req, res) { ; });
And access them with /field/1, /field/3 or whatever.
As described here, the ObjectID for a document is made up of a timestamp, a machine id, a process id, and a counter. I don't see a way to take the counter by itself and come up with the ObjectID. Using a regular expression to search the index probably isn't a good idea because you would end up iterating over all ObjectIDs in the index. As pointed out here, only simple prefix regular expressions can take advantage of the index. Furthermore, I think multiple documents could have the same counter, e.g. if a write occurred on two different machines to the same collection.
So the short answer is "no". If you really want short IDs you probably should roll your own sequence numbers, use something like shortid, or just look the documents up by a naturally unique index (if your collection happens to have one), like email, username, etc.

Mongoose: Only return one embedded document from array of embedded documents

I've got a model which contains an array of embedded documents. This embedded documents keeps track of points the user has earned in a given activity. Since a user can be a part of several activities or just one, it makes sense to keep these activities in an array. Now, i want to extract the hall of fame, the top ten users for a given activity. Currently i'm doing it like this:
userModel.find({ "stats.activity": "soccer" }, ["stats", "email"])
.desc("stats.points")
.limit(10)
.run (err, users) ->
(if you are wondering about the syntax, it's coffeescript)
where "stats" is the array of embedded documents/activeties.
Now this actually works, but currently I'm only testing with accounts who only has one activity. I assume that something will go wrong (sorting-wise) once a user has more activities. Is there anyway i can tell mongoose to only return the embedded document where "activity" == "soccer" alongside the top-level document?
Btw, i realize i can do this another way, by having stats in it's own collection and having a db-ref to the relevant user, but i'm wondering if it's possible to do it like this before i consider any rewrites.
Thanks!
You are correct that this won't work once you have multiple activities in your array.
Specifically, since you can't return just an arbitrary subset of an array with the element, you'll get back all of it and the sort will apply across all points, not just the ones "paired" with "activity":"soccer".
There is a pretty simple tweak that you could make to your schema to get around this though. Don't store the activity name as a value, use it as the key.
{ _id: userId,
email: email,
stats: [
{soccer : points},
{rugby: points},
{dance: points}
]
}
Now you will be able to query and sort like so:
users.find({"stats.soccer":{$gt:0}}).sort({"stats.soccer":-1})
Note that when you move to version 2.2 (currently only available as unstable development version 2.1) you would be able to use aggregation framework to get the exact results you want (only a particular subset of an array or subdocument that matches your query) without changing your schema.

Resources