Reputation: 1280
I'm building a 'jobs' or 'professional resume' webapp. Here's my data model set up:
I have a resume Model:
class Resume(ndb.Model):
full_name = ndb.StringProperty(required = True)
education = ndb.StructuredProperty(Education, repeated = True)
experience = ndb.StructuredProperty(Experience, repeated = True)
skill = ndb.StructuredProperty(Skill, repeated = True)
Here is the Skill(ndb.Model)
for the skill
ndb.StructuredProperty(Skill)
inside the Resume(ndb.Model)
:
class Skill(ndb.Model):
skill = ndb.StringProperty(required = True)
description = ndb.TextProperty()
I'd like to achieve the following:
Resume
entities associated with that skill. skill
s are actually available as they are typing? It would be a bad experience to repeatedly search for skill which does not exist. Thank you for any tip.
Upvotes: 1
Views: 1424
Reputation: 6201
Read about filtering by structured properties here. For you case query will look like:
Resume.query(Resume.skill.skill == 'python').fetch(10)
Autocompleting is a little big harder to do on app engine. You can use prefix queries for this. I think that you should store all available skills in separate kind with key as lower cased skill name. "Python" -> ndb.Key('Skills', 'python')
def query_by_prefix(model, prefix):
""" Returns NDB query with filter by key prefix.
"""
prefix = str(prefix)
return (model.query(ndb.AND(model.key >= ndb.Key(model, prefix),
model.key <= ndb.Key(model, prefix + u'\ufffd'))))
class Skills(ndb.Model):
""" Save here some skills just with keys.
"""
pass
skills = query_by_prefix(Skills, 'p').fetch(10) # you will get up to 10 skills which starts with "p".
You should think about memcaching autocomplete related stuff. This operations will be quoted as "Read", not "Small" operation. It's also possible to build autocomplete by saving all possible prefixes with words into datastore. Here some sample code...
class Autocomplete(ndb.Model):
""" Key here is first letter of the skill. Skills with the same letter should be saved in one entity.
"""
skills = ndb.PickleProperty()
# populate our Autocomplete model first..
all_skills = ['python', 'app-engine', 'django', 'java', 'android']
d = dict()
[d.setdefault(w[0:1], []).append(w) for w in all_skills] # build dict like {'a': ['android', 'app-engine']}
ndb.put_multi([Autocomplete(key=ndb.Key(Autocomplete, k), skills=d[k]) for k in d.keys()]) # put all this stuff into model...
# do the query
query = 'a'
results = Autocomplete.get_by_id(query[0:1].lower())
You will see android and app-engine in results. But it's easy to filter them in memory depending on query. For big datasets you will need to improve this method.
Upvotes: 5