Projection using MongoEngine Raw-Query - python

Does anyone know, how I can implement the following MongoDB query using a MongoEngine Raq-Query?
db.getCollection('subscribers').find({
'_id': ObjectId("579e60b0c525fd2037e8dd31"),
'history.content.read_process_msg': {
'$exists':true
},
'history.content.read_processed': {
'$exists':true
},
'history.content.read_processed': false
},
{'history.$':1})
I read, that the raw-query doesn't support projections and that one should use .only() instead. But the problem here is, that it returns all the empty documents also…
Any advice?
Edit: Here are my models and a sample document:
class Subscriber(Document):
service = StringField()
history = EmbeddedDocumentListField('SubscriberHistory')
def __str__(self):
return self.service
class SubscriberHistory(EmbeddedDocument):
action = StringField()
content = DictField()
def __str__(self):
return self.action
And the sample:
{
"_id" : ObjectId("579e60b0c525fd2037e8dd31"),
"service" : "foo",
"history" : [
{
"action" : "outbound",
"content" : {
"read_processed" : false,
"message_data" : {
"text" : "w00t?"
},
"read_process_msg" : {
"$ref" : "bots_messages",
"$id" : ObjectId("57a6529dc525fd8066ee25b3")
}
},
"created_at" : ISODate("2016-08-06T21:12:00.986Z")
}
]
}

Related

search/filter with list of string graphene-django

I am looking to search for list of different characters/string using graphene-django with single search query run.
class Query(graphene.ObjectType):
candidateInfo = graphene.List(CandidateType, search=graphene.String(),
first=graphene.Int(),
skip=graphene.Int(), last=graphene.Int(),)
def resolve_candidateInfo(self, info, search=None, first=None, last=None, skip=None,
**kwargs):
qs = Candidate.objects.all()
if search:
filter = (
Q(candidateName__icontains=search)|
Q(candidateEmail__icontains=search)|
Q(candidateSkills__icontains=search)
)
qs = qs.filter(filter)
return qs
Here the candidateName, candidateSkills, candidateEmail are in Candidate class with models.CharField
With a single string/character search i am getting correct output. But it fails with list of sting/characters.
Edited: Adding json sample:
[
{
"model": "api.candidate",
"pk": 1,
"fields": {
"candidateName" : "Jack",
"candidateEmail" : "Jack#gmail.com",
"candidateSkills" : ["machine learning", "Artificial Intelligence"]
}
},
{
"model": "api.candidate",
"pk": 2,
"fields":{
"candidateName" : "John",
"candidateEmail" : "John#gmail.com",
"candidateSkills" : ["python", "machine learning"]
}
},
{
"model": "api.candidate",
"pk": 3,
"fields":{
"candidateName" : "Smith",
"candidateEmail" : "Smith#gmail.com",
"candidateSkills" : ["python"]
}
}
]
If query goes in:
query{
candidateInfo(search: "python")
{
candidateName
candidateEmail
}
}
# output must contain data of John and Smith (from sample json)
Also if query is
query{
candidateInfo(search: ["python","artificial intelligence"])
{
candidateName
candidateEmail
}
}
#output must contain data of Jack, John and smith
Adding models of candidate
from django.db import models
class Candidate(models.Model):
candidateName = models.CharField(max_length=100)
candidateEmail = models.CharField(max_length=100)
candidateSkills = models.CharField(max_length=100)
def __str__(self):
return self.candidateSkills
You can run a for loop as such:
qs = Candidate.objects.all()
if search:
if type(search) == list:
qs_l = []
for search_item in search:
filter = (
Q(candidateName__icontains=search_item)|
Q(candidateEmail__icontains=search_item)|
Q(candidateSkills__icontains=search_item)
)
qs_l.append(qs.filter(filter))
qs = qs_l
else:
filter = (
Q(candidateName__icontains=search)|
Q(candidateEmail__icontains=search)|
Q(candidateSkills__icontains=search)
)
qs = qs.filter(filter)
return qs

I want to reconstruct django view

view.py
class ListDoctor(generics.ListCreateAPIView):
queryset = DoctorList.objects.filter(h_code="h_0001")
serializer_class = DoctorListSerializer
def list(self, request):
doctor = DoctorList.objects.values()
return Response(
{
"doctor": doctor
}
)
data:
"doctor": [
{
"doctorname": "testname1",
"position": "ST",
"h_code_id": "h_0000",
"d_code": "d_0000"
},
{
"doctorname": "testname2",
"position": "CB",
"h_code_id": "h_0000",
"d_code": "d_0001"
},
{
"doctorname": "testname3",
"position": "CM",
"h_code_id": "h_0001",
"d_code": "d_0002"
},
{
"doctorname": "testname4",
"position": "GK",
"h_code_id": "h_0001",
"d_code": "d_0003"
}
]
I would like to change the above code like below.
"h_0000" [
{
"doctorname" : "testname1",
"position" : "ST",
"h_code_id: "h_0000",
"d_code" : "d_0000"
},
{
"doctorname" : "testname2"
"position" : "CB"
"h_code_id: "h_0000",
"d_code" : "d_0001"
}
"h_0001" [
{
"doctorname" : "testname3",
"position" : "CM",
"h_code_id: "h_0001",
"d_code" : "d_0002"
},
{
"doctorname" : "testname4"
"position" : "GK",
"h_code_id: "h_0001",
"d_code" : "d_0003"
}
How can I change the data above to look like below?
We sincerely appreciate those who respond.
h_code_id(h_0001, h_0002, h_0003...) will increase gradually. Therefore, it cannot be manually created.
I assume you want to transform the data in different format.
def list(self, request):
data = {}
doctors = DoctorList.objects.values()
for doctor in doctors:
try:
data[doctor["h_code_id"]].append(doctor)
except KeyError:
data[doctor["h_code_id"]] = [doctor]
return Response(data)

AttributeError: 'list' object has no attribute 'update'

I am trying to update the value of project['submission']['status'] to queued for each matching version as below but running into a compilation error,any pointers on how to fix it is really appreicated?
from pymongo import MongoClient
from bson.objectid import ObjectId
import os,pymongo
dbuser = os.environ.get('muser', '')
dbpass = os.environ.get('mpwd', '')
uri = 'mongodb://{dbuser}:{dbpass}#machineip/data'.format(**locals())
client = MongoClient(uri)
db = client.data
collection = db['test']
print db.version
cursor = collection.find({})
cursor = collection.find({})
for document in cursor:
if document['version'] == '9.130.39.0.32.6.1':
for project in document['projects']:
print project
print project['name']
print project['_id']
id = project['_id']
print project['submission']['status']
if project['submission']['status'] != 'queued':
print "Inside Update.."
#project['submission']['status'] = 'queued'
collection_projects = document['projects']
#print collection_projects
for project in collection_projects:
project.update(
{ "_id": ObjectId(id) },
{
"$set": {
"sanity": "queued"
}
})
Document:
{
"_id" : ObjectId("5a95a1c32a2e2e0025e6d6e2"),
"status" : "Submitting",
"sanity" : "none",
"version" : "9.130.39.0.32.6.1",
"requestTime" : ISODate("2018-02-27T18:21:55.764Z"),
"projects" : [
{
"name" : "BCMFurm_4364_B2_ekans",
"_id" : ObjectId("5a95a1c32a2e2e0025e6d6eb"),
"submission" : {
"status" : "passed", --> this status should change to "queued"
"system" : "machine.com"
}
},
{
"name" : "BCMFurm_4364_B2_sid",
"_id" : ObjectId("5a95a1c32a2e2e0025e6d6ea"),
"submission" : {
"status" : "passed",--> this status should change to "queued"
"system" : "machine.com"
}
},
{
"name" : "BCMFurm_4364_Notes",
"_id" : ObjectId("5a95a1c32a2e2e0025e6d6e3"),
"submission" : {
"status" : "passed",--> this status should change to "queued"
"system" : "machine.com"
}
}
],
"Notes" : [],
}
Error:-
"sanity": "queued"
TypeError: update expected at most 1 arguments, got 2
UPDATE:-
'''
for document in cursor:
if document['version'] == '9.130.39.0.32.6.1':
for project in document['projects']:
print project
project_id = project['_id']
if project['submission']['status'] != 'queued':
project.update(
{ "_id" : ObjectId(project_id)},
{ "$set":
{
"submission.status": "queued"
}
}
)
'''
for document in cursor:
docId = document['_id']
print "docId"
print docId
if document['version'] == '9.130.39.0.32.6.1':
for project in document['projects']:
print "project"
print project
projectId = project['_id']
print "projectId"
print projectId
document.update({ "_id": ObjectId(docId), "projects._id": ObjectId(projectId) },
{
'$set': {
'projects.$.submission.status': 'queued'
}
}
)
Following works,it should be collection.update instead of db.update
for document in cursor:
docId = document['_id']
print "docId"
print docId
if document['version'] == '9.130.39.0.32.6.1':
for project in document['projects']:
print "project"
print project
projectId = project['_id']
print "projectId"
print projectId
collection.update({ "_id": ObjectId(docId), "projects._id": ObjectId(projectId) },
{
'$set': {
'projects.$.submission.status': 'queued'
}
}
)
Try:
for project in document['projects']:
print project
print project['name']
print project['_id']
id = project['_id']
print project['submission']['status']
if project['submission']['status'] != 'queued':
print "Inside Update.."
project.update({"sanity": "queued"})
This will add the property "sanity":"queued" to the project in the loop. Is that what you want?
The value to the key "projects" is a list, not a dictionary. You need to append your new list:
collection_projects.append([
{ "_id": ObjectId(id) },
{
"$set": {
"sanity": 'queued'
}])
And change the syntax as such.
You have to update your document.
var docId = document._id;
var projectId = project._id;
document.update({ "_id": ObjectId(docId), "projects._id": ObjectId(projectId) },
{
'$set': {
'projects.$.submission.status': 'queued'
}
}
);
This should work.
You can also iterate all the projects assign the status and at the end of iteration update the whole document at once, this will also work.

list array of objects using python flask

i have a payload as shown below which is stored in mongodb
{
"_id" : ObjectId("5865fbf5558b670ac091c81e"),
"sensors" : [
{
"sensorStatus" : "green ",
"sensorName" : "s1"
},
{
"sensorStatus" : "red ",
"sensorName" : "s2"
}
],
"camera" : [
{
"cameraName" : "cam1",
"cameraStatus" : "live"
},
{
"cameraName" : "cam2",
"cameraStatus" : "live"
}
],
"checkpoints" : [
{
"checkPointName" : "chk1"
}
]
}
trying to write route to display this data as shown below
#gateway_bp.route('/gateway',methods=['GET'])
def list_gateWay():
gateways = Gateway.query.all()
print gateways
return Response(json.dumps(gateways), mimetype='application/json')
i am getting the error has
TypeError: <app.model.canvasmodel.Gateway object at 0x02E99D10> is not JSON serializable
the schema is as shown below
from app.dbconfig.extensions import db
class Sensors(db.Document):
sensorName = db.StringField()
sensorStatus = db.StringField()
class Camera(db.Document):
cameraName = db.StringField()
cameraStatus = db.StringField()
class Checkpoints(db.Document):
checkPointName = db.StringField()
class Gateway(db.Document):
sensors = db.ListField(db.DocumentField(Sensors), db_field='sensors')
camera = db.ListField(db.DocumentField(Camera), db_field='camera')
checkpoints = db.ListField(db.DocumentField(Checkpoints), db_field='checkpoints')
please help to correct the get request thanks

Tastypie list endpoints added using prepend_urls

I am trying to figure out how to show all endpoints from an API I've written. In browsing to the root of the API, I see a list of resources and a single get endpoint. How do I generate a list to show all endpoints? I tried django-tastypie-swagger but had the same results. It only listed a few GET methods for each resource and didn't show all the prepend_urls that I added to the resource. Any help is appreciated!
Edit:
I have some helper methods in the get_manufacturer_wedges to help with the response. Side note, I'm very new to python and this whole stack. I come from a c#.net background. I am building a golf app.
class ManufacturerResource(BaseMongoResource):
class Meta:
max_limit = 0
queryset = Manufacturer.objects.all().order_by('id')
allowed_methods = ('get')
resource_name = 'manufacturers'
include_resource_uri = False
def prepend_urls(self):
return [
url(r"^(?P<resource_name>%s)/(?P<pk>[\w\d_.-]+)/wedges/$" % self._meta.resource_name,
self.wrap_view('get_manufacturer_wedges'), name="api_get_manufacturer_wedges"),
]
def get_manufacturer_wedges(self, request, **kwargs):
prim_key = kwargs['pk'] + "|Wedge"
wedges = Club.objects(_id__startswith=prim_key).order_by('name')
return self.create_response(request, HelperMethods.obj_to_list(wedges))
Here is the output when I go to the root of the api (/api/v1/):
{
"file_upload" : {
"schema" : "/api/v1/file_upload/schema/",
"list_endpoint" : "/api/v1/file_upload/"
},
"members" : {
"schema" : "/api/v1/members/schema/",
"list_endpoint" : "/api/v1/members/"
},
"manufacturers" : {
"schema" : "/api/v1/manufacturers/schema/",
"list_endpoint" : "/api/v1/manufacturers/"
},
"courses" : {
"schema" : "/api/v1/courses/schema/",
"list_endpoint" : "/api/v1/courses/"
},
"clubs" : {
"schema" : "/api/v1/clubs/schema/",
"list_endpoint" : "/api/v1/clubs/"
}
}

Categories