Hi i have a problem with queries data using mongoengine. I try to do this same like in documentation but i have a problem.
I create two models
class Alarm(mongoengine.Document):
added = mongoengine.DateTimeField()
title = mongoengine.StringField()
tracks = mongoengine.ListField(mongoengine.EmbeddedDocumentField(Track))
meta = {
'indexes': [[("tracks.location", "2dsphere")]]
}
class Track(mongoengine.EmbeddedDocument):
created_on = mongoengine.DateTimeField()
location = mongoengine.PointField()
from django shell i add one row :
db.alarm.insert({"title": "Warszawa", "tracks": [{"location": {"type": "Point", "coordinates": [21.01666, 52.233333]}}]})
I connect to mongodb and from shell i try to find my new location using $near:
>db.alarm.find({'tracks.location': {$near: {$geometry: {"type": "Point", coordinates: [18.068611, 59.329444]}, $maxDistance: 810997}}})
>
> db.alarm.find({'tracks.location': {$near: {$geometry: {"type": "Point", coordinates: [18.068611, 59.329444]}, $maxDistance: 810998}}})
{
"_id" : ObjectId("53ef89626dda06655a57a342"), "title" : "Warszawa",
"tracks" : [ { "location" : { "type" : "Point", "coordinates" : [
21.01666, 52.233333 ] } } ] }
Returned result is that what i expected. First query return none second find my location.
But i cannot receive this same result using mongoengine
Alarm.objects(tracks__location__near = {"coordinates":[ 21.01666, 52.233333 ] , "type": "Point"}, tracks__location__max_distance=810998)
i get:
<repr(<mongoengine.queryset.queryset.QuerySet at 0x7ff3a50e8a10>) failed: pymongo.errors.OperationFailure: database error: Can't canonicalize query: BadValue geo near accepts just one argument when querying for a GeoJSON point. Extra field found: $maxDistance: 810998>
This is more like a hint, but:
$near operator in MongoDB has two subclauses: $geometry and $maxDistance (that's how you call it in the Mongo shell). But it looks like your custom object tries to instantiate $near clause with only $geometry as parameter.
So it's not tracks__location__max_distance, but rather something like tracks__location__near__max_distance (i.e. max_distance should be inside $near clause).
Related
I am trying to combine two SQLAlchemyConnectionField. The current error i face is graphql.error.base.GraphQLError: Expected value of type "PostsObject" but got: Tag
My current connections are defined like so posts = SQLAlchemyConnectionField(PostsObject.connection, /* input arguments like posts(name: "") */) Is there a way to add another type or allow to return something like
"data": {
"posts": {
"edges": [
{
"node": "Different table"
},
{
"node": "Other table"
}]}},
I am using graphene_sqlalchemy well anyway thats all thanks !
I am trying to get the highest value for nr from a mongo database collection named prob that looks like this for now:
{
"_id": {
"$oid": "5ae9d062f36d282906c59736"
},
"nr": 1,
"nume": "numeunu",
"enunt": "-",
"datedeintrare": "-",
"datedeiesire": "-"
}
{
"_id": {
"$oid": "5ae9f190f36d282906c5b461"
},
"nr": 2,
"nume": "numedoi",
"enunt": "-",
"datedeintrare": "-",
"datedeiesire": "-"
}
My testing flask code is:
#app.route('/test')
def testaree():
prob = mongo.db.prob
return prob.find().sort({"nr":-1}).limit(1)
but it gives me an error TypeError: if no direction is specified, key_or_list must be an instance of list
The syntax for sorting using pymongo is different from the mongo query language.
In the above code the expression used is
sort({"nr":-1})
However , that is a mongo shell query syntax. When using pymongo it should be
sort("nr", pymongo.DESCENDING)
You could also use find_one instead of a limit clause once the data is sorted.
db.prob.find_one(sort=[("nr", pymongo.DESCENDING)])
I was trying to update PointField in my flask app with upsert_one. But it always inserts new document. I know the problem is with the query which I'm passing.
Below is my model.
class Location(db.Document):
location_name = db.StringField(required=True)
geoCoords = db.PointField()
And the update query.
Location.objects(geoCoords=loc["geoCoords"]).upsert_one(location_name=loc["location_name"], geoCoords=loc["geoCoords"])
#loc["geoCoords"] = [77.6309395,12.9539974]
I also tried running get. But I'm getting the error message "Location matching query does not exist." for the below query.
loc = Location.objects(geoCoords=[77.6309395,12.9539974]).get()
I have following entries in my location collection.
> db.location.find()
{ "_id" : ObjectId("59c5019727bae70ad3259e67"), "geoCoords" : { "type" : "Point", "coordinates" : [ 77.6309395, 12.9539974 ] }, "location_name" : "Bengaluru" }
{ "_id" : ObjectId("59c5022d27bae70ad3259ea2"), "geoCoords" : { "type" : "Point", "coordinates" : [ 77.6309395, 12.9539974 ] }, "location_name" : "Bengaluru" }
>
I couldn't find any related information on querying the PointFiled.
To answer to my question. I think there is no way to get the exact points like I have mentioned in the question.
The nearest method works here is to use __near selector. This accepts the range in meters. So, you can give closest range query as per your requirement.
In my case, I gave 100 meters. Which is fine for me.
Example:
Location.objects(geoCoords__near=thelocation["geoCoords"], geoCoords__max_distance=100).upsert_one(location_name=thelocation["location_name"], geoCoords=thelocation["geoCoords"])
Try this:
Location.objects(geoCoords="...").update(location_name=loc["location_name"], geoCoords=loc["geoCoords"])
I am getting data from one collection using python and I will be processing it and storing it in another collection. In the processed collection some of the date fields looks different like Date(-61833715200000).
I use below code to get data and processing it and then I bulk insert the values to new collection.
fleet_managers = taximongo.users.aggregate([{ "$match": { "role" : "fleet_manager"}}])
fleet_managers = pd.DataFrame(list(fleet_managers))
fleet_managers['city_id'] = fleet_managers['region_id'].map({'57ff2e84f39e0f0444000004':'Chennai','57ff2e08f39e0f0444000003':'Hyderabad'})
pros_fleet_managers.insert_many(fleet_managers.to_dict('records'))
The collection looks like this:
{
"_id" : ObjectId("58006678ee5e0e29c5000009"),
"deleted_at" : NaN,
"region_id" : "57ff2e84f39e0f0444000004",
"reset_password_sent_at" : Date(-61833715200000),
"current_sign_in_at" : ISODate("2016-10-14T06:07:55.568Z"),
"last_sign_in_at" : ISODate("2016-10-14T06:07:45.574Z"),
"remember_created_at" : Date(-61833715200000)
}
What did do wrong here. Thanks already.
I have found the solution by using the $ifNull while projecting the fields.
fleet_managers = taximongo.users.aggregate([{ "$match": { "role" : "fleet_manager"}},{"$project":{'_id':1,'deleted_at':{ "$ifNull": [ "$deleted_at", "null" ] },
'reset_password_sent_at':{ "$ifNull": [ "$reset_password_sent_at", "null" ] }, 'region_id':1,'current_sign_in_at':1,'last_sign_in_at':1,'remember_created_at':{ "$ifNull": [ "$remember_created_at", "null" ] }}}])
fleet_managers = pd.DataFrame(list(fleet_managers))
fleet_managers['city_id'] = fleet_managers['region_id'].map({'57ff2e84f39e0f0444000004':'Chennai','57ff2e08f39e0f0444000003':'Hyderabad'})
pros_fleet_managers.insert_many(fleet_managers.to_dict('records'))
The above code gives the solution but I need to handle the null or non existence dynamically i.e., when fetching it from the source collection.
Help me out on this.
Data:
{
"_id" : ObjectId("50cda9741d41c81da6000002"),
"template_name" : "common_MH",
"role" : "MH",
"options" : [
{
"sections" : [
{
"tpl_option_name" : "test321",
"tpl_option_type" : "string",
"tpl_default_value" : "test321"
}
],
"tpl_section_name" : "Test"
}
]
}
could I modify tpl_default_value in options.$.section.$.tpl_option_name = 'test321'?
I already try too times, but I can't solve.
please assist me, thanks.
This is a bad schema for doing these kinda of updates, there is a JIRA for multi-level positional operator however it is not yet done: https://jira.mongodb.org/browse/SERVER-831
Ideally you either have to update this client side and then atomically set that section of the array:
$section = {
"tpl_option_name" : "test321",
"tpl_option_type" : "string",
"tpl_default_value" : "test321"
};
db.col.update({}, {$set: {options.$.sections.1: $section}})
Or you need to change your schema. Does the sections really need to be embedded? I noticed that you have a tpl_section_name in the top level but then you are nesting sections within that, it sounds more logical that only one section should be there.
That document would be easier to update.