添加索引到属性

时间:2017-07-13 17:00:14

标签: google-cloud-datastore google-app-engine-python

除了将实体重写到数据存储区之外,还有一种方法可以将现有实体属性编入索引吗?

方案: 我使用先前创建的实体的属性创建了新查询。 查询失败,"无法查询未编入索引的属性",这是正确的行为,因为初始类定义具有(indexed = false) 相关财产。

然后我为相关属性设置(indexed = true)。使用此属性的查询比运行时没有生成错误,输出却是INCORRECT!

我认为这是因为现有实体不会自动添加到索引中(尽管Google文档会避免自动生成索引)。

我只能通过更新每个实体来更新索引并使查询正常工作。如果人们意识到问题在于使用小数据集,那么这也许没问题。我关注实时数据。我需要在现场进行更多测试,但相同的效果/行为可能是相同的。

似乎更改了index.yaml并重新启动GAE实例没有任何效果。它也会出现gcloud数据存储区创建索引index.yaml不会影响此行为。

似乎是一种解决方案 似乎唯一的解决方案是回写现有实体,以便在新索引中创建一个条目。可能是因为:

all_entities_in_kind=theModel.query()
list_of_keys= ndb.put_multi(all_entities_in_kind)

如果有更好的方式请发帖。

模拟效果 为了说明,我在Dev SDK Interactive控制台中运行了下面的代码片段。首次运行以下代码可创建测试数据。查询将失败(正确的行为)。

将bool_p更改为indexed = true,重新运行修改后的代码意味着查询将运行但结果不正确。

删除所有数据并重新运行代码(使用bool_p索引)查询返回正确的结果。

观察 看来属性上的索引不会自动生成。至少从Interactive控制台。重新启动实例无效。更改index.yaml文件似乎没有任何区别。它似乎是需要建立的属性索引,但到目前为止我还没有发现如何。唯一的解决方案是导出所有数据并使用修改后的类重新导入。这不是开发中的问题,而是实时数据存储的问题。

代码示例

from google.appengine.ext import ndb
from datetime import datetime, timedelta

class TModel(ndb.Model):
    test_date = ndb.DateProperty(indexed=True)
    text = ndb.StringProperty(indexed=True)
    bool_p = ndb.BooleanProperty(indexed=False) #First run
    #bool_p = ndb.BooleanProperty(indexed=True) #Second run.

query0=TModel.query()
if query0.count() == 0:
    print 'Create test data'
    TModel(id='a',test_date=datetime.strptime('2017-01-01','%Y-%m-%d').date(),text='One',bool_p=True).put()
    TModel(id='b',test_date=datetime.strptime('2017-01-02','%Y-%m-%d').date(),text='Two',bool_p=False).put()
    TModel(id='c',test_date=datetime.strptime('2017-01-03','%Y-%m-%d').date(),text='Three',bool_p=True).put()
    TModel(id='d',test_date=datetime.strptime('2017-01-01','%Y-%m-%d').date(),text='One').put() #To check behaviour with bool_p undefined

query1 = TModel.query(TModel.bool_p == True)
print query1.count()

query2 = TModel.query(TModel.bool_p == False)
print query2.count()

query3 = TModel.query(TModel.test_date <= datetime.strptime('2017-01-02','%Y-%m-%d').date())
print query3.count()

query4 = TModel.query(TModel.test_date <= datetime.strptime('2017-01-02','%Y-%m-%d').date(), TModel.bool_p == True)
print query4.count()

#Equivalent Queries using GQL
queryG1=ndb.gql('SELECT * FROM TModel WHERE bool_p = True')
print queryG1.count()

queryG2=ndb.gql('SELECT * FROM TModel WHERE bool_p = True')
print queryG2.count()

queryG3 =ndb.gql("SELECT * FROM TModel WHERE test_date <= DATE('2017-01-02')")
print queryG3.count()

queryG4 =ndb.gql("SELECT * FROM TModel WHERE test_date <= DATE('2017-01-02') AND bool_p = True ")
print queryG4.count()

将更改后的结果/错误结果更改为:(indexed = False)为True

2 0
1 0
3 3
1 0
2 0
2 0
3 3
1 0

1 个答案:

答案 0 :(得分:0)

在将属性从未索引更改为索引时,必须重写现有实体,以便重新索引属性。来自https://cloud.google.com/datastore/docs/concepts/indexes#unindexed_properties

  

但是,请注意,将属性从排除更改为索引不会影响在更改之前可能已创建的任何现有实体。对属性进行查询过滤将不会返回此类现有实体,因为实体在创建时未写入查询索引。要使实体可以通过将来的查询访问,您必须将它们重写为Cloud Datastore,以便将它们输入到适当的索引中。