Best way to query a DictField in MongoEngine - mongoengine

I've been hunting through the mongoengine documentation and around stack overflow and there doesn't seem to be a very clear answer to this so I'm asking: how do you best query a DictField?
example code:
class Note(Document):
someData = DictField()
note = Note()
note.someData['someID'] = {"name": "Steve", "age":25}
note.save()
The closest I could find in the docs would be:
Note.objects(someData__name="Steve")
but that hasn't been working
Again, feel like this should be a simple answer. Thanks for your help

You have wrong request, because you miss someID.
See you structure in db:
>>> db.note.findOne()
>>> {
"_id": ObjectId("'0'*24")
"someData": {
"someID": {
{"name": "Steve", "age":25}
}
}
}
So right request will be Note.objects(someData__someID__name="Steve").

Related

Node.js/MongoDB - querying dates

I'm having a bit of an issue understanding how to query dates; I think the issue might be with how my data is structured. Here is a sample document on my database.
{
"phone_num": 12553,
"facilities": [
"flat-screen",
"parking"
],
"surroundings": [
"ping-pong",
"pool"
],
"rooms": [
{
"room_name": "Standard Suite",
"capacity": 2,
"bed_num": 1,
"price": 50,
"floor": 1,
"reservations": [
{
"checkIn": {
"$date": "2019-01-10T23:23:50.000Z"
},
"checkOut": {
"$date": "2019-01-20T23:23:50.000Z"
}
}
]
}
]
}
I'm trying to query the dates to see check if a specific room is available at a certain date-range but no matter what I do I can't seem to get a proper result, either my query 404's or returns empty array.
I really tried everything, right now for simplicity I'm just trying to get the query to work with checkIn so I can figure out what I'm doing wrong. I tried 100 variants of the code below but I couldn't get it to work at all.
.find({"rooms": { "reservations": { "checkIn" : {"$gte": { "$date": "2019-01-09T00:00:00.000Z"}}}}})
Am I misunderstanding how the .find method works or is something wrong with how I'm storing my dates? (I keep seeing people mentioning ISODates but not too sure what that is or how to implement).
Thanks in advance.
I think the query you posted is not correct. For example, if you want to query for the rooms with the checkin times in a certain range then the query should be like this -
.find({"rooms.reservations.checkout":{$gte:new Date("2019-01-06T13:11:50+06:00"), $lt:new Date("2019-01-06T14:12:50+06:00")}})
Now you can do the same with the checkout time to get the proper filtering to find the rooms available within a date range.
A word of advice though, the way you've designed your collection is not sustainable in the long run. For example, the date query you're trying to run will give you the correct documents, but not the rooms inside each document that satisfy your date range. You'll have to do it yourself on the server side (assuming you're not using aggregation). This will block your server from handling other pending requests which is not desirable. I suggest you break the collection down and have rooms and reservations in separate collections for easier querying.
Recently I was working on date query. First of all we need to understand how we store date into the mongodb database. Say I have stored data using UTC time format like 2020-07-21T09:45:06.567Z.
and my json structure is
[
{
"dateOut": "2020-07-21T09:45:06.567Z",
"_id": "5f1416378210c50bddd093b9",
"customer": {
"isGold": true,
"_id": "5f0c1e0d1688c60b95360565",
"name": "pavel_1",
"phone": 123456789
},
"movie": {
"_id": "5f0e15412065a90fac22309a",
"title": "hello world",
"dailyRentalRate": 20
}
}
]
and I want to perform a query so that I can get all data only for this( 2020-07-21) date. So how can we perform that?. Now we need to understand the basic.
let result = await Rental.find({
dateOut: {
$lt:''+new Date('2020-07-22').toISOString(),
$gt:''+new Date('2020-07-21').toISOString()
}
})
We need to find 21 date's data so our query will be greater than 21 and less than 22 cause 2020-07-21T00:45:06.567Z , 2020-07-21T01:45:06.567Z .. ... .. this times are greater than 21 but less than 22.
var mydate1 = new Date();
var mydate1 = new Date().getTime();
ObjectId.getTimestamp()
Returns the timestamp portion of the ObjectId() as a Date.
Example
The following example calls the getTimestamp() method on an ObjectId():
ObjectId("507c7f79bcf86cd7994f6c0e").getTimestamp()
This will return the following output:
ISODate("2012-10-15T21:26:17Z")
If your using timestamps data to query.
EG : "createdAt" : "2021-07-12T16:06:34.949Z"
const start = req.params.id; //2021-07-12
const data = await Model.find({
"createdAt": {
'$gte': `${start}T00:00:00.000Z`,
'$lt': `${start}T23:59:59.999Z`
}
});
console.log(data);
it will show the data of particular date .i.,e in this case. "2021-07-12"

GraphQL Conditional Queries

I'm a newbie in GraphQL and I was wondering if there is a easy way to query with "dynamic conditions".
For exemple, on GraphiQL I can query for :
query {
users{
name
age
}
}
And It will bring me a list of all users
{
"data": {
"users": [
{
"name": "Luis Coimbra",
"age": 15
},
{
"name": "SebastiĆ£o Campagnucci",
"age": 50
},
{
"name": "Giovana Ribeiro",
"age": 30
}
]
}
}
But is there an easy way for me to bring only, for example, users who are above 18 or any other age ?
An expected solution would be:
query {
users{
name
age > 18
}
}
Haven't found anything like that on documentation...
This is possible-it would have to be different. Your query wouldn't be a valid GQL query. Something like this would:
{
users(where: {age: { $gt: 18 }}){ #inspired by mongoDB query api
name
age
}
}
or maybe simpler:
{
users(where: {age: ">18"}}){
name
age
}
}
of course either way the resolver on the backend needs to expect this where argument on the users field and construct the DB query accordingly when it is passed. You would not find this in GraphQL docs because GraphQL itself doesn't care about that. It only showcases how to use features of GraphQL.
If you tried example projects like for example star was api, those don't have any filtering built in.
You should send your age filter as a parameter.You might try the following one:
In your graphql file
type users {
name: String,
age: Int,
...
}
usersQuery(ageLimit: Int): [users]
also you can send '>' , '<' , '=' as a parameter. Also it seems like that
usersQuery(ageLimit: Int, ageOperator: String): [users]
and you should configure your resolver where statement with these operators. hope it helps you.

Sequelize.js: how to sort query results based on values in where in closure ?

I issue the next query:
Users.findAll({
where : {
user_id: {
in : [ data.user_id, data.user_id_to_replace ]
}
}
}).then(function(results){})
I would like the results would be sorted by the order I have in the where in closure, i.e. first come for data.user_id and only then data.user_id_to_replace. I know how to do this in javascript, but I'm looking if there is a param in Sequelize that does this job for me. Thanks.
Ok, seems there is no sequelize built-in solution to my problem. Then here is a method using underscore I used for sorting finally. Hope this will be helpful someone looking to solve the same issue:
_.sortBy(results, function(item) {
return item.get('user_id') === data.user_id ? 0 : 1
})

one way direction, sails and mongodb

I have a question. I think i am doing something wrong.
I have two models:
tutorType and Student.
Here is my Student
module.exports = {
attributes: {
tutor1Name:'string',
tutor1Type: {
model: 'tutorType'
},
contact: {
type: 'numeric'
},
}
};
And here is my TutorType
module.exports = {
attributes: {
libelle: "string"
}
};
I use the predefined blue print to insert. When i Insert a new student
I have the returned response:
{
"name": "Luke",
"tutor1Type": "Biological",
"createdAt": "2015-07-13T17:57:12.526Z",
"updatedAt": "2015-07-13T17:57:12.526Z",
"id": "55a3fbf8c9e93bf0266a63a8"
}
Should tutor1Type be an object instead of a String? Actually, I can put the string I want. I would like to be able to put only rows i have in TutorType with a foreign key on my Student.
What wrong I do?!
EDIT
Just add a look in my DB.
When I send the ID of the tutorType to my controller. It add an "Object(hashID)" in db. I presume that is a good news.
The things is that I can also insert string that are not into my tutorList...
I do not understand how integrity work right here...
Any ideas?!

How do I sort 'auto-magically' using Mongoose?

Say I have a URL like this:
http://dev.myserver.com/systems?system_type.category=Penetration
which hits the following controller:
exports.findAll = function(req, res) {
System.find(req.query, function(err, systems) {
res.send(systems);
});
};
and then returns the set below 'auto-magically' using Node, Express, MongoDB and Mongoose:
[{
"_id": "529e5f29c128685d860b3bad",
"system_number": "123",
"target_country": "USA",
"system_type": {
"category": "Penetration",
"subcategory": ["Floor", "Wall"]
}
},{
"_id": "999e5f29c128685d860b3bad",
"system_number": "456",
"target_country": "Canada",
"system_type": {
"category": "Penetration",
"subcategory": ["Floor", "Wall"]
}
}]
Now, if I want the results sorted by 'target_country', what is the 'best practice' for 'auto-magically' doing that?
Are there certain parameters/syntax that Mongoose/Express are expecting to do it for me? Or, is this a case where I have to specifically code for it? (That would kill the 'auto-magical' functionality already there.)
Thanks!
UPDATE: Here is what worked for me.
exports.findAll = function(req, res) {
// Sort Ascending:
http://dev.dom.com/systems?system_type.category=Penetration&sort=system_number
// Sort Descending:
http://dev.dom.com/systems?system_type.category=Penetration&sort=-system_number
// Default sort ascending on system_number:
http://dev.dom.com/systems?system_type.category=Penetration
var sort_param = req.query.sort ? req.query.sort : 'system_number';
System.find().sort(sort_param).find(function(err, menus) {
res.send(menus);
});
};
I guess where I went wrong, was to think I should find with filters and then sort, instead of find all, sort and then find again with filters. Still getting my head wrapped around the whole 'callback philosophy' I guess.
You need to define separate URL parameters for the query and sort components of your System query. As in:
System.find(req.query.query).sort(req.query.sort).exec(function(err, systems) {
res.send(systems);
});
Then you'd use request URL parameters that look like:
?sort=target_country
&query[system_type.category]=Penetration
&query[system_type.subcategory]=Floor
Docs on sort here.

Resources