尽管提供了索引,但Google App Engine中的NeedIndexError仍然存在

时间:2017-03-24 16:14:49

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

我使用命令行SDK上传了我的index.yaml文件: adding index.yaml via command line

不幸的是,我现在将我的一些实体编入索引两次(但它们都在服务): enter image description here

但是我在运行页面时仍然遇到“需要索引错误”:

NeedIndexError: no matching index found. recommended index is:
- kind: RouteDetails
  ancestor: yes
  properties:
  - name: RouteName
    direction: desc

The suggested index for this query is:
- kind: RouteDetails
  ancestor: yes
  properties:
  - name: RouteName
    direction: desc

如何让Google App Engine识别我的实体索引?

如何删除重复项? (我需要吗?)

3 个答案:

答案 0 :(得分:1)

当查询扫描多个属性或是祖先查询时,数据存储区要求为每种查询类型创建显式索引。如果您有不同的查询类型,那么种类肯定会被多次编入索引。

例如:

SELECT * FROM RouteDetails
WHERE __key__ HAS ANCESTOR KEY(ParentKind, 'foo')
ORDER BY RouteName ASC

需要升序索引。

- kind: RouteDetails
  ancestor: yes
  properties:
  - name: RouteName
    direction: asc

并且

SELECT * FROM RouteDetails
WHERE __key__ HAS ANCESTOR KEY(ParentKind, 'foo')
ORDER BY RouteName DESC

需要单独的降序索引。

- kind: RouteDetails
  ancestor: yes
  properties:
  - name: RouteName
    direction: desc

https://cloud.google.com/datastore/docs/concepts/indexes

在您的情况下,您似乎正在使用RouteName属性的降序ORDER BY执行祖先查询,并将建议的索引添加到index.yaml文件中应该为您解决问题。

对于疑似"重复",哪些索引需要存在取决于您的应用程序执行的特定查询。

但是如果你确定你有额外的未使用的索引,可以在这里找到真空索引的说明:https://cloud.google.com/datastore/docs/tools/indexconfig#Datastore_Deleting_unused_indexes

答案 1 :(得分:1)

索引包含按方向排序 - 您可以在控制台视图中看到向上箭头,指示所有字段都在升序。

建议的索引是其中一个属性的降序索引。

你的重复'索引已由reason字段引入,您将其编入索引为大写字母r和小写字母r,它们是不同的命名字段

答案 2 :(得分:0)

以防万一其他人偶然发现这个问题并遇到类似的问题。

它正在寻找带有ancestor: yes的索引的原因是我使用了错误的查询,并且根本不应该有一个祖先密钥。

这是我的新查询:

class RouteDetails(ndb.Model):
    """Get list of routes from Datastore """
    RouteName = ndb.StringProperty()

    @classmethod
    def query_routes(cls):
        return cls.query().order(-cls.RouteName)


class RoutesPage(webapp2.RequestHandler):
    def get(self):
        adminLink = authenticate.get_adminlink()
        authMessage = authenticate.get_authmessage()
        self.output_routes(authMessage,adminLink)

    def output_routes(self,authMessage,adminLink):
        self.response.headers['Content-Type'] = 'text/html'
        html = templates.base
        html = html.replace('#title#', templates.routes_title)
        html = html.replace('#authmessage#', authMessage)
        html = html.replace('#adminlink#', adminLink)
        self.response.out.write(html + '<ul>')
        list_name = self.request.get('list_name')
        #version_key = ndb.Key("List of routes", list_name or "*notitle*")
        routes = RouteDetails.query_routes().fetch(20)

        for route in routes:
            self.response.out.write('<li>%s</li>' % route)
        self.response.out.write('</ul>' + templates.footer)

我正在使用文档的这个页面,它没有告诉你如何构建一个没有祖先的类的查询。

https://cloud.google.com/appengine/docs/standard/python/datastore/queries