当前位置: 首页 > 知识库问答 >
问题:

如何正确使用spring数据的二级索引

裴兴言
2023-03-14

我有一个名为order的couchbase bucket,其中包含将近2000个文档,我为此bucket创建了一个二级索引(idx_customer),以优化我的查询:

在couchbase查询监视器中执行时,查询命中索引。

但我认为,当从spring数据存储库播放时,它错过了索引。这主要是因为存储库中的排序和分页使我的查询在其他没有索引的查询中被翻译。

CREATE INDEX idx_customer ON `order` (
buyer.contact.firstName , 
buyer.contact.lastName , 
ALL DISTINCT ARRAY aoc.`communicationValue` FOR aoc IN buyer.contact.communicationChannel
WHEN aoc.`communicationChannelCode`= "EMAIL" END)
WHERE _class = "com.lbk.entities.OrderEntity"

我使用此存储库中的spring数据在spring boot应用程序中查询订单:

import com.lbk.entities.OrderEntity;
import com.lbk.entities.OrderMetadataEntity;
import org.springframework.data.couchbase.core.query.N1qlPrimaryIndexed;
import org.springframework.data.couchbase.core.query.N1qlSecondaryIndexed;
import org.springframework.data.couchbase.core.query.Query;
import org.springframework.data.couchbase.core.query.ViewIndexed;
import org.springframework.data.couchbase.repository.CouchbasePagingAndSortingRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.List;

@ViewIndexed(designDoc = "orderEntity")
@N1qlSecondaryIndexed(indexName = "idx_customer")
@N1qlPrimaryIndexed
public interface OrdersRepository extends CouchbasePagingAndSortingRepository<OrderEntity, String> {

    List<OrderMetadataEntity> findAllBy();

    Page<OrderMetadataEntity> findAllBy(Pageable page);

    @Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} "
                    + "AND orderTypeCode = $1 "
                    + "AND (orderCategory != $2 OR orderCategory is not valued ) "
                    + "AND buyer.contact.firstName is not null"
    )
    Page<OrderMetadataEntity> findOrders(String orderTypeCode, String excludedOrderCategory, Pageable page);

    @Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} "
                    + "AND creationDateTime >= STR_TO_MILLIS($1) AND creationDateTime <= STR_TO_MILLIS($2) "
                    + "AND orderTypeCode = $3 "
                    + "AND (orderCategory != $4 OR orderCategory is not valued )"

"ANDbuyer.contact.firstName is not null")Page findOrdersByCreationDateTime在(String start, String end, String orderTypeCode, String排除dOrderClass,可分页页面);

}

但是性能和日志记录显示,对于sur,我没有使用索引,这是怎么了?如何查询正确的二级索引形成我的存储库?

对于此分页N1QL查询:

@Query("#{#n1ql.selectEntity} WHERE #{#n1ql.filter} "
                                + "AND orderTypeCode = $1 "
                                + "AND (orderCategory != $2 OR orderCategory is not valued ) "
                                + "AND buyer.contact.firstName is not null")
Page<OrderMetadataEntity> findOrders(String orderTypeCode, String excludedOrderCategory, Pageable page);

我在日志中有三个查询:

  1. 查询统计文档。
  2. 查询获取文档的第一页。
  3. 查询获取子文档(SELECTARRAY_LENGTH(orderLineItem))(我想知道为什么!!!)。

以下是Spring数据日志:

Executing N1QL query: {\"args\":[\"%mohammed%\",\"%mohammed%\",null,\"220\",\"EXECLUDED_CATEGORY\"],\"statement\":\"SELECT COUNT(*) AS count FROM `order` WHERE `_class` = \\"com.lbk.entities.OrderEntity\\" AND ( LOWER(buyer.contact.firstName) LIKE $1 OR LOWER(buyer.contact.lastName) LIKE $2 OR ANY communicationChannel IN buyer.contact.communicationChannel SATISFIES ( communicationChannel.communicationChannelCode = 'EMAIL' AND communicationChannel.communicationValue  = $3 ) END )  AND orderTypeCode = $4 AND (orderCategory != $5 OR O2.orderCategory is not valued )AND creationDateTime in (select RAW max(O2.creationDateTime) from `order` O2 WHERE ( LOWER(O2.buyer.contact.firstName) LIKE $1 OR LOWER(O2.buyer.contact.lastName) LIKE $2 OR ANY communicationChannel IN O2.buyer.contact.communicationChannel SATISFIES ( communicationChannel.communicationChannelCode = 'EMAIL' AND communicationChannel.communicationValue  = $3 ) END )  AND ANY communicationChannel IN O2.buyer.contact.communicationChannel SATISFIES ( communicationChannel.communicationChannelCode = 'EMAIL' AND communicationChannel.communicationValue is not null ) END AND O2.orderTypeCode = $4 AND (O2.orderCategory != $5 OR O2.orderCategory is not valued) group by ( ARRAY item.communicationValue FOR item IN O2.buyer.contact.communicationChannel WHEN item.communicationChannelCode = 'EMAIL' END ) )AND buyer.contact.firstName IS NOT NULL\",\"scan_consistency\":\"statement_plus\"}
Executing N1QL query: {\"args\":[\"%mohammed%\",\"%mohammed%\",null,\"220\",\"EXECLUDED_CATEGORY\"],\"statement\":\"SELECT META(`order`).id AS _ID, META(`order`).cas AS _CAS, `order`.* FROM `order` WHERE `_class` = \\"com.lbk.entities.OrderEntity\\" AND ( LOWER(buyer.contact.firstName) LIKE $1 OR LOWER(buyer.contact.lastName) LIKE $2 OR ANY communicationChannel IN buyer.contact.communicationChannel SATISFIES ( communicationChannel.communicationChannelCode = 'EMAIL' AND communicationChannel.communicationValue  = $3 ) END )  AND orderTypeCode = $4 AND (orderCategory != $5 OR O2.orderCategory is not valued )AND creationDateTime in (select RAW max(O2.creationDateTime) from `order` O2 WHERE ( LOWER(O2.buyer.contact.firstName) LIKE $1 OR LOWER(O2.buyer.contact.lastName) LIKE $2 OR ANY communicationChannel IN O2.buyer.contact.communicationChannel SATISFIES ( communicationChannel.communicationChannelCode = 'EMAIL' AND communicationChannel.communicationValue  = $3 ) END )  AND ANY communicationChannel IN O2.buyer.contact.communicationChannel SATISFIES ( communicationChannel.communicationChannelCode = 'EMAIL' AND communicationChannel.communicationValue is not null ) END AND O2.orderTypeCode = $4 AND (O2.orderCategory != $5 OR O2.orderCategory is not valued) group by ( ARRAY item.communicationValue FOR item IN O2.buyer.contact.communicationChannel WHEN item.communicationChannelCode = 'EMAIL' END ) )AND buyer.contact.firstName IS NOT NULL ORDER BY `creationDateTime` DESC LIMIT 18 OFFSET 0\",\"scan_consistency\":\"statement_plus\"}
Executing N1QL query: {\"args\":[\"069cf983-8ed7-4b8f-845d-175593d4ca49\"],\"statement\":\"SELECT ARRAY_LENGTH(orderLineItem) FROM `order` WHERE `_class` = \\"com.lbk.entities.OrderEntity\\" AND META().id = $1\",\"scan_consistency\":\"statement_plus\"}

谢谢

共有1个答案

吕征
2023-03-14

查询将无法使用idx_客户索引,因为它不符合条件。请在中签出“在Couchbase N1QL中为查询设计索引”https://blog.couchbase.com/n1ql-practical-guide-second-edition

该索引是部分索引,并且只有包含_class=“com.lbk.entities.OrderEntity”的文档的条目,但您的任何查询都不会包含此谓词,因此无法使用该索引。此外,查询谓词(谓词的每个或部分)必须使用hvae前导索引键作为查询谓词才能使用索引。对于日志中的查询,情况并非如此。如果需要,可以尝试使用非部分索引。

CREATE INDEX idx_customer1 ON `order` (_class, 
buyer.contact.firstName , 
buyer.contact.lastName , 
ALL DISTINCT ARRAY aoc.`communicationValue` FOR aoc IN buyer.contact.communicationChannel
WHEN aoc.`communicationChannelCode`= "EMAIL" END);
 类似资料:
  • 我正在使用Spring 4.0.0. RELEASE,Spring数据共享1.7.0. M1,Spring Hateoas 0.8.0. RELEASE 我的资源是一个简单的POJO: 我的资源汇编程序将User对象转换为UserResources对象: 在我的UserController我想检索

  • 我正在尝试记录来自iPhone加速度计(我自己的iPhone5s)的数据,并使用在屏幕上为该数据设置标签,其中data是我要记录的特定轴的值。为此,我设置了一个CMMotionManager并开始记录加速度计数据,并且我有一个定时器可以不断更新标签中的文本。但是,我从Xcode收到一个错误:“致命错误:在展开可选值时意外发现为nil”。以下是相关代码: 当我更改accelX时,错误停止。文本赋值给

  • 问题内容: 我正在使用Selenium IDE为我的站点编写测试,但是我无法让selenium使用上一个同级按钮单击按钮 我自己的路 问题答案: 您无需升级并使用,因为所有按钮都处于同一级别:

  • 是否可以正确地升级,而不是手动安装最新的稳定版本? 我已安装节点。js版本和,但现在我想将其更新为。我试图避免手动重新安装所有全局软件包(例如,通过运行grunt cli bower yoman angular generator blablablablablablablablablablabla)。

  • 问题内容: 我已经读到,使用hibernate的二级缓存,它可以通过减少对数据/对象检索的数据库命中次数来提高应用程序性能。 但是,hibernate如何确保二级缓存与数据库中的数据保持最新。 例如: 假设下面的类是实体并且持久化到数据库中。 现在,如果我们启用了二级缓存,我知道如果打开不同的会话,则每个会话都将命中二级缓存以获取对象值。 现在,如果数据库中的数据发生更改(例如,对于ID = 1的

  • 我想从这个HTML中解析数据(CompanyName,Location,jobDescription,...)使用JSoup(java)。我在尝试迭代工作列表时会被卡住 从HTML中提取是我想要迭代并从中提取数据的许多“joblisting”div中的一个。我只是无法处理如何迭代特定的div对象。很抱歉这个问题,但也许有人可以帮助我谁已经知道使用哪一个功能。选择? 文件输入=新文件(“C:/tal