代码之家  ›  专栏  ›  技术社区  ›  Andrey Yaskulsky

使用contains运算符查询全局辅助索引

  •  0
  • Andrey Yaskulsky  · 技术社区  · 3 年前

    我一直在阅读DynamoDB的文档,无法理解使用“contains”运算符查询Global Secondary Index是否有意义。

    我的问题如下:我的dynamoDB文档有一个嵌入对象的列表,每个对象都有一个唯一的“代码”字段:

        {
    
         "entities":[
                {"code":"entity1Code", "name":"entity1Name"}, 
                {"code":"entity2Code", "name":"entity2Name"}
           ]
    
       }
    

    我希望能够获取包含实体的所有文档 entity.code = X . 为此,我正在考虑添加一个包含所有 entity.codes 存在于当前数据库文档中,用逗号分隔。所以上面的例子看起来像:

        {
    
         "entities":[
                {"code":"entity1Code", "name":"entity1Name"}, 
                {"code":"entity2Code", "name":"entity2Name"}
           ],
         "entitiesGlobalSecondaryIndex":"entityCode1,entityCode2"
       }
    

    然后我想在上应用筛选器表达式 entitiesGlobalSecondaryIndex 类似于: entitiesGlobalSecondaryIndex contains entityCode1 .

    这是有效的吗?还是使用全局二级索引在这种方式下没有意义,DynamoDB只会根据每个类似的文档检查条件,所以扫描?

    非常感谢您的帮助,

    谢谢

    0 回复  |  直到 3 年前
        1
  •  0
  •   lynkfox    3 年前

    查询的contains运算符不能在分区键上运行。为了使查询使用任何类型的运算符(包含、以、><ect…开头),您必须有一个范围属性,也就是排序键。

    你可以很好地设置一个GSI,其中一些值作为你的PK,这个代码作为你的SK。然而,GSI 表的复制-GSI中的数据有可能落后于主副本的数据。如果你对这个GSI进行的查询不是很频繁,那么你可能是安全的。

    然而如果你试图同时对整张桌子进行扫描,那么这并不比扫描更好。

    如果你需要一个特定的代码来一次返回所有文档,那么你可以用它作为PK来做一个GSI。如果你添加一个日期字段作为这个GSI的SK,它甚至会被时间排序。如果你查询索引中的代码,你会得到它们中的每一个。

    由于您可能有多个代码,如果每个文档的代码不太多,您可以使用稀疏索引-如果您有一个代码为“AAAA”的实体,那么您也有一个名为AAAA(或AAAAflag或其他什么)的属性。它总是空/不存在 除非 实体包含该代码。如果对此AAAflag属性执行GSI,它将只包含包含该实体代码的文档,并忽略给定文档中不存在该属性的所有文档。如果你也能提供一个很好的PK来保持数字的良好分区,并且你没有太多的代码,这可能对你有用。

    顺便说一下,Filter表达式与上述所有表达式都不同。筛选表达式是在将要返回的数据从表中读取后对其运行的。这很有用——我希望您有一个多访问模式设置,但不希望通过特定的调用来获取与特定PK相关的所有文档——为了保持代码使用的数据简洁。带有过滤器表达式的查询仍然从该查询中检索所有内容,但只显示通过过滤器的内容。

    如果在任何给定的时间只查询特定的PK,并且您想知道它是否包含x的任何实体,那么Filter表达式将完美工作。当然,这只是每个PK,而不是整个表格。

    如果您只需要数字,那么您可以在文档上创建count属性,或者在包含这些值的分区上创建一个可以直接查询的元文档。

    最后,我不知道这是否有效,如果你的entities属性是一种映射类型,你很可能能够根据entities代码进行过滤,甚至可以根据entities.code.contains(value)进行过滤,如果它是SK,但我不知道是否可能

    推荐文章