【问题标题】:NeedIndexError in Google App Engine, despite indexes being served尽管提供了索引,但 Google App Engine 中的 NeedIndexError
【发布时间】:2017-03-24 16:14:49
【问题描述】:

我已经使用命令行 SDK 上传了我的 index.yaml 文件:

不幸的是,我的一些实体现在被索引了两次(但它们都在服务):

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

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 识别我的实体索引?

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

【问题讨论】:

  • 顺便说一句,我也看了这个问题:stackoverflow.com/questions/29807215/… 和这个:stackoverflow.com/questions/33388390/… 这让我中途但仍然得到这个错误
  • 如果你仔细看你会发现这两个看起来一样的索引是不一样的。不是出于原因/原因。这是两个不同属性名称“原因”和“原因”的两个不同索引
  • 是的,我不小心添加了一个带有小写“原因”的内容,然后添加了一个带有大写“原因”的内容以尝试更正它,最终得到了两个。

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


【解决方案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

【讨论】:

  • 谢谢,我现在已经成功更新了我的索引,但我仍然遇到同样的错误。我不太清楚祖先的事情实际上是如何工作的,我想知道这是否是导致错误的原因
  • 所以结果证明我使用了错误的查询,因为它根本不应该有祖先键。但是我已经让它工作并从我的数据存储中提供了一条数据,所以是的,谢谢。
【解决方案2】:

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

建议的索引是属性之一的降序索引。

reason 字段引入了您的“重复”索引,您将其索引为大写 r 和小写 r,它们是不同的命名字段

【讨论】:

  • 谢谢。是的,我不小心添加了一个小写的“原因”,然后添加了一个大写的原因作为尝试纠正它,最后得到了两个,这就是为什么我需要知道如何摆脱其中。
【解决方案3】:

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

它寻找带有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

【讨论】:

  • 我将此作为答案发布,以便我可以将代码放入其中。请注意,上面的查询返回带有所有属性的路线,而您可能想要更具体。
猜你喜欢
  • 2015-06-30
  • 1970-01-01
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 2016-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多