【问题标题】:Apache Ignite : Ignite Repository query with "IN" clause, returns no recordsApache Ignite:带有“IN”子句的 Ignite Repository 查询,不返回任何记录
【发布时间】:2019-07-25 09:41:45
【问题描述】:

我在 SpringBoot 应用程序中使用 Apache Ignite 作为后端数据存储。 我有一个要求,我需要从一组名称中获取名称与其中一个名称匹配的所有实体。

因此我尝试使用@Query 配置和名为findAllByName(Iterable<String> names) 的方法来实现它,如下所示: 在Query 上,我正在尝试使用'IN' 子句并希望将names 的数组作为'IN' 子句的输入传递。

@RepositoryConfig(cacheName = "Category")
public interface CategoryRepository extends IgniteRepository<Category, Long> 
{
List<Category> findByName(String name);
@Query("SELECT * FROM Category WHERE name IN ( ? )")
Iterable<Category> findAllByName(Iterable<String> names); // this method always returns empty list .
}

在这种情况下,方法 findAllByName 总是返回空列表,即使 ignite 具有 Categories ,其中 name 字段与查询中传递的数据匹配。 我无法确定语法或方法签名或参数的查询是否有问题。

【问题讨论】:

    标签: sql spring-data ignite in-clause


    【解决方案1】:

    我知道您的问题更具体到 Spring Data Ignite 功能。但是,作为替代方案,您可以使用 Ignite 的 SqlQuery 抽象来实现它。

    您将像这样形成您的查询。我已将下面的示例粘贴到您将编写的自定义 sql 函数 inSet 中。此外,下面会告诉您如何在您的 sql 中使用它。

    IgniteCache<String, MyRecord> cache = this.ignite
        .cache(this.environment.getProperty(Cache.CACHE_NAME));
    
    String sql = "from “my-ignite-cache”.MyRecord WHERE  
    MyRecord.city=?  AND inSet(?, MyRecord.flight)"
    
    SqlQuery<String, MyRecord> sqlQuery = new SqlQuery<>(MyRecord.class,
        sql);
    
    sqlQuery.setArgs(MyCity, [Flight1, Flight2 ] );
    
    QueryCursor<Entry<String, MyRecord>> resultCursor = cache.query(sqlQuery);
    

    您可以迭代结果游标以从提取的数据中做一些有意义的事情。

    resultCursor.forEach(e -> {
        MyRecord record = e.getValue();
    // do something with result
    });
    

    下面是上述查询中使用的 Ignite Custom Sql function - 这将有助于复制 IN 子句功能。

    @QuerySqlFunction
    public static boolean inSet(List<String> filterParamArgIds, String id) {
        return filterParamArgIds.contains(id);
    }
    

    最后,作为参考,上面提到的MyRecord 可以这样定义。

    public class MyRecord implements Serializable {
    
        @QuerySqlField(name = "city", index = true)
        private String city;
    
        @QuerySqlField(name = "flight", index = true)
        private String flight;
    }
    

    【讨论】:

      【解决方案2】:

      请尝试使用String[] names 代替提供参数。

      更新:我刚刚检查了来源,我们没有针对这种情况的测试。这意味着即使有可能开始工作,您仍处于未知领域。 否则目前看起来不受支持。

      【讨论】:

      • 此更改无济于事:'@Query("SELECT * FROM Category WHERE name IN ( ? )") Iterable&lt;Category&gt; findAllByName(String[] names); ' 这不会返回任何记录
      • @alamar - 虽然这仍然不受支持 - 解决此用例的推荐方法是什么?你会建议通过 SQLQuery API 而不是 ignite repo 吗?
      • @NeerajSingh getAll() 的 Cache API 应该没问题
      猜你喜欢
      • 1970-01-01
      • 2022-09-25
      • 2022-07-23
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      • 2019-04-07
      • 1970-01-01
      • 2019-03-07
      相关资源
      最近更新 更多