使用自定义类作为Ignite键时是否可以查询嵌套字段?

问题描述 投票:0回答:1

[使用Apache Ignite 2.7.6,我正在尝试创建一个缓存,该缓存的键是其中包含多个字段的自定义类,并且将其嵌入值中。缓存有效,但是SQL界面向我显示了嵌套键中字段的空值。而且,当我将这些字段设为表的主键时,结果似乎违反了标准SQL,因为在主键中允许多个null值。有什么办法可以使这项工作吗?

以下是可复制的示例:

@Test
public void testComplexKey() throws InterruptedException {
    val queryEntity = new QueryEntity(TestKey.class, TestValue.class);
    // I get the same results regardless of whether these 2 lines are present or not
    queryEntity.getFields().put("key", TestKey.class.getName());
    queryEntity.setKeyFieldName("key");
    // I get the same results regardless of whether this lines is present or not
    queryEntity.setKeyFields(Sets.newHashSet("key.firstName", "key.lastName"));
    queryEntity.getFields().put("key.firstName", String.class.getName());
    queryEntity.getFields().put("key.lastName", String.class.getName());
    queryEntity.getFields().put("data", String.class.getName());
    queryEntity.setTableName("test_values");
    val cache = ignite.getOrCreateCache(
            new CacheConfiguration<TestKey, TestValue>()
                    .setName("test_values")
                    .setQueryEntities(Lists.newArrayList(queryEntity))
    );
    cache.put(new TestKey("Bob", "Jones"), new TestValue(new TestKey("Bob", "Jones"), "The quick red fox jumped over the lazy brown dog"));
    cache.put(new TestKey("Jim", "Smith"), new TestValue(new TestKey("Jim", "Smith"), "The quick red dog jumped over the lazy brown fox"));
    Assertions.assertEquals("The quick red fox jumped over the lazy brown dog", cache.get(new TestKey("Bob", "Jones")).data);
    // This assertion would fail - no rows found
    // Assertions.assertEquals("The quick red fox jumped over the lazy brown dog", cache.query(new SqlQuery<TestKey, TestValue>(TestValue.class, "firstName = 'Bob'")).getAll().stream().findFirst().orElseThrow().getValue().data);
    // This just to keep the test running and allow me to query the SQL interface
    while (true) Thread.sleep(10000);
}

@NoArgsConstructor // This is Lombok shorthand
@AllArgsConstructor
public static class TestKey {
    @Getter
    @Setter
    String firstName;

    @Getter
    @Setter
    String lastName;
}

@NoArgsConstructor
@AllArgsConstructor
public static class TestValue {
    @Getter
    @Setter
    TestKey key;

    @Getter
    @Setter
    String data;
}

生成的SQL视图...相当令人困惑:

SQL View depicting two rows both with NULL/NULL primary key values

ignite
1个回答
2
投票

在SQL引擎中,所有对象都被“展平”,因此您将key.firstName称为firstName

queryEntity.setKeyFields(Sets.newHashSet("firstName", "lastName"));
queryEntity.getFields().put("firstName", String.class.getName());
queryEntity.getFields().put("lastName", String.class.getName());
queryEntity.getFields().put("data", String.class.getName());

大多数人发现在要公开给SQL的属性上使用@QuerySqlField批注更容易。

无需在值中包含键对象。删除它还会消除您所引用的“ firstName”列的歧义。

© www.soinside.com 2019 - 2024. All rights reserved.