Python AppEngine数据存储以查询“结束”

Python AppEngine数据存储以查询“结束”,python,google-app-engine,python-2.7,google-cloud-datastore,Python,Google App Engine,Python 2.7,Google Cloud Datastore,关于这个答案:我发现可以使用以下方法来完成“开始于”: MyModel.all().filter('prop >=', prefix).filter('prop <', prefix + u'\ufffd') domains | reverse_domain ------- | -------------- .com.io | oi.moc. .com.eu | ue.moc. .com.mx | xm.moc. 如果我想查询以“.io”结尾的域,我应该执行以下操作: suffi

关于这个答案:我发现可以使用以下方法来完成“开始于”:

MyModel.all().filter('prop >=', prefix).filter('prop <', prefix + u'\ufffd')
domains | reverse_domain
------- | --------------
.com.io | oi.moc.
.com.eu | ue.moc.
.com.mx | xm.moc.
如果我想查询以“.io”结尾的域,我应该执行以下操作:

suffix = '.io'
MyModel.all().filter(
    'reverse_domain >=', suffix).filter(
    'reserve_domain <', suffix + u'\ufffd')
但在测试时,在python命令行上进行字符串比较时,我得到以下结果:

>>> '.com.io'[::-1] >= '.io'
True
>>> '.com.io'[::-1] < '.io' +  u'\ufffd'
False
更改顺序,首先是u'\ufffd',然后是后缀

因此,想知道在执行“结束于”时,除了颠倒存储数据的顺序外,u'\ufffd'是否应该先执行,类似于这样:

MyModel.all().filter(
    'reverse_prop >=', suffix).filter(
    'reverse_prop <', u'\ufffd' + suffix)
在比较字符串时,是否遵循与python相同的词典顺序

基本上,如何做一个:

SELECT domain FROM domains WHERE <domain name> LIKE CONCAT('%', domain)
例如,如果我搜索google.com.io,我可以得到域'.com.io',那么,如何获得以某物结尾的现有域/字符串的列表

更新:


虽然测试似乎只需要将操作符>=更改为,如果您的用例涉及搜索顶级域,我建议将URL拆分为两个单独的属性。这将使查找具有给定TLD的所有记录变得容易,并为其他搜索提供更大的灵活性

你也可以考虑使用一个整数来表示每个TLD,如果你有数百万的记录。它将减少数据的大小


使用一个相等筛选器而不是两个相等筛选器时,这种方法可能会快一点。

在搜索后缀之前,必须先反转后缀,因为索引中的文本也会反转。您的意思是“.com.io”[::-1]>='.io'[:-1]和“.com.io'[:-1]<'.io'[:-1]+u'\ufffd'对。实际上,您只是在反向列上执行前缀搜索,因此您希望使用与StartWith相同的技术来执行StartWith搜索oi。我做了一些测试,除了反转后缀和数据,我似乎还必须将>=运算符更改为您的意思是拆分域,例如['google'、'com'、'io']然后从左到右搜索io.com.google,直到找到匹配项?我的意思是使用两个单独的属性-一个用于google,另一个用于com.io。可能是,我应该将当前数据拆分为顶级域等等。我不知道您的要求,但您也可以使用com.io和其他TLD作为单独的实体类型。这是一个很好的选择,如果你从不搜索所有的域。可能是,但也可能是创建一个实体的io,其他com,并以域结束,如果我需要搜索一个特定的域,我只会搜索他们的父母,而不是像IP->com->gogole的东西,对吗?
SELECT domain FROM domains WHERE <domain name> LIKE CONCAT('%', domain)
suffix = '.io'[::-1]
MyModel.all().filter(
    'reverse_domain <=', suffix).filter(
    'reserve_domain <', suffix + u'\ufffd')
>>> assert('.com.io'[::-1] <= '.com.io'[::-1] and '.com.io'[::-1] < '.com.io'[::-1] + u'\ufffd')

>>> assert('.com.io'[::-1] <= 'google.com.io'[::-1] and '.com.io'[::-1] < 'google.com.io'[::-1] + u'\ufffd') 

>>> assert('.com.io'[::-1] <= 'gle.com.io'[::-1] and '.com.io'[::-1] < 'gle.com.io'[::-1] + u'\ufffd')