【问题标题】:How to convert a n1ql query to use with Spring couchbase reactive repository alongwith @Query annotation?如何将 n1ql 查询转换为与 Spring couchbase 反应式存储库以及 @Query 注释一起使用?
【发布时间】:2023-03-09 19:09:01
【问题描述】:

我正在使用 Spring 的响应式堆栈以及 Spring 的响应式 couchbase 来构建 api,并且需要帮助来转换我想从 ReactiveCouchbaseRepository 使用的查询。

在 couchbase 中创建索引的方法取自这篇文章: https://forums.couchbase.com/t/indexing-array-of-strings/14977

CREATE INDEX idx_emaillist ON api (DISTINCT ARRAY k FOR k IN emails.emaillist END);

我用来搜索的查询是:

SELECT * FROM user AS u WHERE ANY k IN u.emails.emaillist SATISFIES k = "abc@email.com" END;

这个查询的结果是:

[
  {
    "u": {
      "_class": "com.users.api.model.User",
      "name": "abc",
      "emails": {
        "emaillist": [
          "abc@email.com",
          ""xyz@email.com"
        ]
      }
    }
  }
]

我想从扩展 ReactiveCouchbaseRepository 的接口中声明的方法中使用相同的查询。

我也尝试了这张票中指定的方法: Can we Convert N1QL to shEL query for Spring use

这种方法效果很好,但我希望 Spring 处理样板代码,并且还注意到调用是阻塞的,但我希望对 couchbase 进行非阻塞调用。

【问题讨论】:

    标签: reactive-programming spring-data-couchbase


    【解决方案1】:

    如果您没有与电子邮件相关的任何其他属性,那么按照您的做法存储它实际上是一种更好的方法:

    [
      {
        "u": {
          "_class": "com.users.api.model.User",
          "name": "abc",
          "emails": [
              "abc@email.com",
              ""xyz@email.com"
          ]
        }
      }
    ]
    

    请注意,您还必须更改索引。

    这里有一些关于如何为数组创建索引的好链接: https://docs.couchbase.com/server/6.0/n1ql/n1ql-language-reference/indexing-arrays.html https://forums.couchbase.com/t/how-to-correctly-create-array-index/17349 https://blog.couchbase.com/making-the-most-of-your-arrays-with-array-indexing/

    您可以打印由 spring 数据生成的查询: https://blog.couchbase.com/how-to-log-queries-generated-by-spring-data/

    并使用“EXPLAIN”关键字运行查询,以确保您的查询正在使用索引。如果您使用的是企业版,则只需检查查询计划器即可。

    【讨论】:

    • 感谢@deniswsrosa。我会使用这个解决方案本身。我在之前的评论中打印了查询:执行 N1QL 查询:{"args":["ABC"],"statement":"SELECT META(user).id AS _ID, META(user ).cas AS _CAS, user.* FROM user 其中_class = \"com.users.api.model.User\" AND ARRAY_CONTAINS(emails, $1)","scan_consistency":"statement_plus"}当我使用“EXPLAIN”运行查询并使用主索引“CREATE PRIMARY INDEX #primary ON user”时,我认为它没有使用我创建的索引,所以会删除索引。
    【解决方案2】:

    我找不到我的问题的答案,但在尝试了更多选项后发现我可以通过更改 JSON 对象的格式来做到这一点。

    发件人:

    [
      {
        "u": {
          "_class": "com.users.api.model.User",
          "name": "abc",
          "emails": {
            "emaillist": [
              "abc@email.com",
              ""xyz@email.com"
            ]
          }
        }
      }
    ]
    

    到这里:

    [
      {
        "u": {
          "_class": "com.users.api.model.User",
          "name": "abc",
          "emails": [
              "abc@email.com",
              ""xyz@email.com"
          ]
        }
      }
    ]
    

    现在响应式沙发库中的方法更改为:

        @Query("#{#n1ql.selectEntity} where #{#n1ql.filter} AND ARRAY_CONTAINS(emails, $1)")
        Flux<User> findByIdEmail(String email);
    

    我进一步检查了日志以查看线程是 I/O 线程还是 nio 线程

    DEBUG 19228 --- [reactor-http-nio-3] s.d.c.r.q.ReactiveAbstractN1qlBasedQuery : Executing N1QL query: {"args":["ABC"],"statement":"SELECT META(`user`).id AS _ID, META(`user`).cas AS _CAS, `user`.* FROM `user` where `_class` = \"com.users.api.model.User\" AND ARRAY_CONTAINS(emails, $1)","scan_consistency":"statement_plus"}
    
    

    我希望这个解决方案也能帮助其他人,但不知道为什么我想用 Object 和 array 来构建结构。 如果我错了,请纠正我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 2021-09-18
      • 2019-05-07
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多