转向ZIG ZAG合并与最佳索引

时间:2013-03-05 16:18:49

标签: google-app-engine indexing objectify

我的应用程序目前定义了所需的所有最佳索引。但慢慢地我开始受到爆炸式索引问题的困扰,所以我想切换我的策略并开始使用“zig-zag”合并,如解释here

我的实体Contact有3个排序顺序:

  • lastModified ASC

  • fullNameUpperCase ASC + DESC

它有4个过滤器:

  • contactProfile

  • contactStatus

  • contactType

  • searchFields(不等式查询以模拟'startsWith ...')

searchFields是一种特殊情况,因为我用它来模仿'startswith'就像这样

 query = query.filter("searchFields >= ", criteria.getSearchString().toUpperCase());
 query = query.filter("searchFields <= ", criteria.getSearchString().toUpperCase() + "\ufffd");

按照文章中的解释,我需要定义

 (number of filters + 1) * (number of orders) = 5 * 3 = 15.
  • 我的主要问题!

下面的新定义似乎适用于开发服务器,但不是第一次。它应该第一次执行zigzag merge的新组合,devserver仍会抛出DatastoreNeedIndexException。第二次重复相同的查询,查询运行并返回预期的结果。在分析结果时也会发生这种情况。我第一次查询下一页时,会抛出异常。重复工作。有人也见过这种行为吗?这个devserver问题还是我错过了什么?或者这个索引构建起初可能是不完整的......例如devserver抱怨这是我第一次组合这些过滤器时作为索引丢失的:

<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactProfile" direction="asc"/>
    <property name="status" direction="asc"/>
    <property name="fullNameUpperCase" direction="desc"/>
</datastore-index>

以下是entity Contact的新索引定义:

<!-- SORT ORDERS -->
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="desc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="lastModified" direction="desc" />
</datastore-index>
<!-- FILTER: SEARCHFIELDS -->
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="asc" />
    <property name="searchFields" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="desc" />
    <property name="searchFields" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="lastModified" direction="desc" />
    <property name="searchFields" direction="asc" />
</datastore-index>
<!-- FILTER: CONTACTSTATUS -->
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="asc" />
    <property name="status" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="desc" />
    <property name="status" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="lastModified" direction="desc" />
    <property name="status" direction="asc" />
</datastore-index>
<!-- FILTER: CONTACTTYPE -->
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="asc" />
    <property name="contactType" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="desc" />
    <property name="contactType" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="lastModified" direction="desc" />
    <property name="contactType" direction="asc" />
</datastore-index>
<!-- FILTER: CONTACTPROFILE -->
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="asc" />
    <property name="contactProfile" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="desc" />
    <property name="contactProfile" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="lastModified" direction="desc" />
    <property name="contactProfile" direction="asc" />
</datastore-index>

1 个答案:

答案 0 :(得分:1)

在将排序顺序移动到组合索引中的最后一个属性后,修复了它不起作用的问题。

例如

<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="asc" />
    <property name="status" direction="asc" />
</datastore-index>

必须成为。

<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="status" direction="asc" />
    <property name="fullNameUpperCase" direction="asc" />
</datastore-index>

所以最后一个属性是排序顺序。

其次,seachField必须被视为排序顺序,我必须进行组合。索引现在变成了 5个订单:

  • lastModified ASC

  • fullNameUpperCase ASC + DESC

  • searchFields ASC + DESC

3个过滤器:

  • contactProfile

  • contactStatus

  • contactType

    (过滤器数量+ 1)*(订单数量)= 4 * 5 = 20个索引。

这是完整功能列表:

<!-- SORT ORDERS -->
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="fullNameUpperCase" direction="desc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="lastModified" direction="desc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="searchFields" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="searchFields" direction="desc" />
</datastore-index>
<!-- FILTER: CONTACTSTATUS -->
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="status" direction="asc" />
    <property name="fullNameUpperCase" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="status" direction="asc" />
    <property name="fullNameUpperCase" direction="desc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="status" direction="asc" />
    <property name="lastModified" direction="desc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="status" direction="asc" />
    <property name="searchFields" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="status" direction="asc" />
    <property name="searchFields" direction="desc" />
</datastore-index>
<!-- FILTER: CONTACTTYPE -->
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactType" direction="asc" />
    <property name="fullNameUpperCase" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactType" direction="asc" />
    <property name="fullNameUpperCase" direction="desc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactType" direction="asc" />
    <property name="lastModified" direction="desc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactType" direction="asc" />
    <property name="searchFields" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactType" direction="asc" />
    <property name="searchFields" direction="desc" />
</datastore-index>
<!-- FILTER: CONTACTPROFILE -->
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactProfile" direction="asc" />
    <property name="fullNameUpperCase" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactProfile" direction="asc" />
    <property name="fullNameUpperCase" direction="desc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactProfile" direction="asc" />
    <property name="lastModified" direction="desc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactProfile" direction="asc" />
    <property name="searchFields" direction="asc" />
</datastore-index>
<datastore-index kind="Contact" ancestor="true" source="manual">
    <property name="contactProfile" direction="asc" />
    <property name="searchFields" direction="desc" />
</datastore-index>

PS:我删除了有关如何将生产环境迁移到新索引的其他问题,我会在需要时发布新问题;