如何将 n1ql 查询转换为与 Spring couchbase 反应式存储库以及 @Query 注释一起使用?

How to convert a n1ql query to use with Spring couchbase reactive repository alongwith @Query annotation?

我正在使用 Spring 的反应式堆栈和 Spring 的反应式 couchbase 来构建 api 并且需要帮助来转换我想使用的查询ReactiveCouchbaseRepository.

在 couchbase 中创建索引的方法取自此 post: 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 进行非阻塞调用。

我找不到问题的答案,但在尝试了更多选项后发现我可以通过更改 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"
      ]
    }
  }
]

现在反应式couchbase库中的方法更改为:

    @Query("#{#n1ql.selectEntity} where #{#n1ql.filter} AND ARRAY_CONTAINS(emails, )")
    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, )","scan_consistency":"statement_plus"}

我希望这个解决方案也能帮助其他人,但不确定为什么我要先用对象再用数组来构建结构。 如果我错了请纠正我。

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

[
  {
    "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" 关键字的查询以确保您的查询正在使用索引。如果您使用的是企业版,您只需检查查询计划器即可。