Google app engine 查询重复属性以开头
假设我有一个电影数据库,你可以通过标题搜索 我有一个Google app engine 查询重复属性以开头,google-app-engine,google-cloud-datastore,app-engine-ndb,Google App Engine,Google Cloud Datastore,App Engine Ndb,假设我有一个电影数据库,你可以通过标题搜索 我有一个电影模型,看起来像下面的(简化) queryName只是Movie.name中单词的小写列表。parent\u key()基本上只是用于查询 如果我在搜索电影《森林阿甘》,我希望它能在以下搜索词中显示出来(还有更多,这些只是示例) “fo”-“forest”以“fo”开头 “gu”-“gump”以“gu”开头 “gu fo”-“forest”以“fo”开头,“gump”以“gu”开头 我可以通过类似于下面的查询轻松获得前两个 movies =
电影
模型,看起来像下面的(简化)
queryName
只是Movie.name
中单词的小写列表。parent\u key()
基本上只是用于查询
如果我在搜索电影《森林阿甘》,我希望它能在以下搜索词中显示出来(还有更多,这些只是示例)
movies = Movie\
.query(ancestor=Movie.parent_key())\
.filter(Movie.queryName >= x)\
.filter(Movie.queryName < x + u'\ufffd')\
.feth(10)
更新:
我目前的解决办法是
class MovieSearchHandler(BaseHandler):
def get(self):
q = self.request.get('q')
if q:
q = q.replace('&', '&').lower().split()
movieFilter, reducable = self.create_filter(*q)
if movieFilter:
movies = Movie\
.query(ancestor=Movie.parent_key())\
.filter(movieFilter)\
.fetch(None if reducable else 10)
if reducable:
movies = self.reduce(movies, q)
return self.write_json([{'id': m.movieId, 'name': m.name} for m in movies])
return self.write_json([])
def create_filter(self, *args):
if args:
if len(args) == 1:
prefix = args[0]
return ndb.AND(Movie.queryName >= prefix, Movie.queryName < prefix + u'\ufffd'), False
ands = [ndb.AND(Movie.queryName >= prefix, Movie.queryName < prefix + u'\ufffd')
for prefix in args]
return ndb.OR(*ands), True
return None, False
def reduce(self, movies, terms):
reducedMovies = []
for m in movies:
if len(reducedMovies) >= 10:
return reducedMovies
if all(any(n.startswith(t) for n in m.queryName) for t in terms):
reducedMovies.append(m)
return reducedMovies
class MovieSearchHandler(BaseHandler):
def get(自我):
q=self.request.get('q')
如果q:
q=q.replace('&','&;').lower().split()
电影过滤器,可还原=自创建过滤器(*q)
如果是电影过滤器:
电影\
.query(祖先=Movie.parent\u key())\
.过滤器(电影过滤器)\
.fetch(如果可还原,则为无,否则为10)
如果可还原:
电影=自我减少(电影,q)
返回self.write_json([{'id':m.movieId,'name':m.name}表示电影中的m])
返回self.write_json([])
def create_过滤器(自身,*参数):
如果参数为:
如果len(args)==1:
前缀=args[0]
返回ndb.AND(Movie.queryName>=前缀,Movie.queryName=前缀,Movie.queryName=10:
返回还原移动
如果全部(任何(n.startswith(t)表示m.queryName中的n)表示t,则以术语表示:
reducedMovies.append(m)
返回还原移动
不过还是在找更好的
谢谢你有没有考虑过使用全文搜索,或者“嗖”的一声,我不认为你能从直接的数据存储中得到你想要的。是的,我想说的是,使用全文搜索可以很容易地做到,但我的问题已经太长了。然而,我不想满足于此,因为我觉得这真的损害了可用性。谢谢你。
movies = Movie\
.query(ancestor=Movie.parent_key())\
.filter(Movie.queryName >= 'fo')\
.filter(Movie.queryName < 'fo' + u'\ufffd')\
.filter(Movie.queryName >= 'gu')\
.filter(Movie.queryName < 'gu' + u'\ufffd')\
.feth(10)
class MovieSearchHandler(BaseHandler):
def get(self):
q = self.request.get('q')
if q:
q = q.replace('&', '&').lower()
filters = self.create_filter(*q.split())
if filters:
movies = Movie\
.query(ancestor=Movie.parent_key())\
.filter(*filters)\
.fetch(10)
return self.write_json([{'id': m.movieId, 'name': m.name} for m in movies])
return self.write_json([])
def create_filter(self, *args):
filters = []
if args:
for prefix in args:
filters.append(Movie.queryName >= prefix)
filters.append(Movie.queryName < prefix + u'\ufffd')
return filters
class MovieSearchHandler(BaseHandler):
def get(self):
q = self.request.get('q')
if q:
q = q.replace('&', '&').lower().split()
movieFilter, reducable = self.create_filter(*q)
if movieFilter:
movies = Movie\
.query(ancestor=Movie.parent_key())\
.filter(movieFilter)\
.fetch(None if reducable else 10)
if reducable:
movies = self.reduce(movies, q)
return self.write_json([{'id': m.movieId, 'name': m.name} for m in movies])
return self.write_json([])
def create_filter(self, *args):
if args:
if len(args) == 1:
prefix = args[0]
return ndb.AND(Movie.queryName >= prefix, Movie.queryName < prefix + u'\ufffd'), False
ands = [ndb.AND(Movie.queryName >= prefix, Movie.queryName < prefix + u'\ufffd')
for prefix in args]
return ndb.OR(*ands), True
return None, False
def reduce(self, movies, terms):
reducedMovies = []
for m in movies:
if len(reducedMovies) >= 10:
return reducedMovies
if all(any(n.startswith(t) for n in m.queryName) for t in terms):
reducedMovies.append(m)
return reducedMovies