Fix rule node query performance
This commit is contained in:
parent
3f10ba464e
commit
e369218a1f
@ -30,7 +30,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public interface RuleNodeDao extends Dao<RuleNode> {
|
public interface RuleNodeDao extends Dao<RuleNode> {
|
||||||
|
|
||||||
List<RuleNode> findRuleNodesByTenantIdAndType(TenantId tenantId, String type, String search);
|
List<RuleNode> findRuleNodesByTenantIdAndType(TenantId tenantId, String type, String configurationSearch);
|
||||||
|
|
||||||
PageData<RuleNode> findAllRuleNodesByType(String type, PageLink pageLink);
|
PageData<RuleNode> findAllRuleNodesByType(String type, PageLink pageLink);
|
||||||
|
|
||||||
|
|||||||
@ -56,8 +56,8 @@ public class JpaRuleNodeDao extends JpaAbstractDao<RuleNodeEntity, RuleNode> imp
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RuleNode> findRuleNodesByTenantIdAndType(TenantId tenantId, String type, String search) {
|
public List<RuleNode> findRuleNodesByTenantIdAndType(TenantId tenantId, String type, String configurationSearch) {
|
||||||
return DaoUtil.convertDataList(ruleNodeRepository.findRuleNodesByTenantIdAndType(tenantId.getId(), type, search));
|
return DaoUtil.convertDataList(ruleNodeRepository.findRuleNodesByTenantIdAndType(tenantId.getId(), type, configurationSearch));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -29,19 +29,22 @@ import java.util.UUID;
|
|||||||
|
|
||||||
public interface RuleNodeRepository extends JpaRepository<RuleNodeEntity, UUID> {
|
public interface RuleNodeRepository extends JpaRepository<RuleNodeEntity, UUID> {
|
||||||
|
|
||||||
@Query("SELECT r FROM RuleNodeEntity r WHERE r.ruleChainId in " +
|
@Query(nativeQuery = true, value = "SELECT * FROM rule_node r WHERE r.rule_chain_id in " +
|
||||||
"(select id from RuleChainEntity rc WHERE rc.tenantId = :tenantId) " +
|
"(select id from rule_chain rc WHERE rc.tenant_id = :tenantId) AND r.type = :ruleType " +
|
||||||
"AND r.type = :ruleType AND LOWER(r.configuration) LIKE LOWER(CONCAT('%', :searchText, '%')) ")
|
" AND (:searchText IS NULL OR r.configuration ILIKE CONCAT('%', :searchText, '%'))")
|
||||||
List<RuleNodeEntity> findRuleNodesByTenantIdAndType(@Param("tenantId") UUID tenantId,
|
List<RuleNodeEntity> findRuleNodesByTenantIdAndType(@Param("tenantId") UUID tenantId,
|
||||||
@Param("ruleType") String ruleType,
|
@Param("ruleType") String ruleType,
|
||||||
@Param("searchText") String searchText);
|
@Param("searchText") String searchText);
|
||||||
|
|
||||||
@Query("SELECT r FROM RuleNodeEntity r WHERE r.type = :ruleType AND LOWER(r.configuration) LIKE LOWER(CONCAT('%', :searchText, '%')) ")
|
@Query(nativeQuery = true, value = "SELECT * FROM rule_node r WHERE r.type = :ruleType " +
|
||||||
|
" AND (:searchText IS NULL OR r.configuration ILIKE CONCAT('%', :searchText, '%'))")
|
||||||
Page<RuleNodeEntity> findAllRuleNodesByType(@Param("ruleType") String ruleType,
|
Page<RuleNodeEntity> findAllRuleNodesByType(@Param("ruleType") String ruleType,
|
||||||
@Param("searchText") String searchText,
|
@Param("searchText") String searchText,
|
||||||
Pageable pageable);
|
Pageable pageable);
|
||||||
|
|
||||||
@Query("SELECT r FROM RuleNodeEntity r WHERE r.type = :ruleType AND r.configurationVersion < :version AND LOWER(r.configuration) LIKE LOWER(CONCAT('%', :searchText, '%')) ")
|
@Query(nativeQuery = true, value = "SELECT * FROM rule_node r WHERE r.type = :ruleType " +
|
||||||
|
" AND configuration_version < :version " +
|
||||||
|
" AND (:searchText IS NULL OR r.configuration ILIKE CONCAT('%', :searchText, '%'))")
|
||||||
Page<RuleNodeEntity> findAllRuleNodesByTypeAndVersionLessThan(@Param("ruleType") String ruleType,
|
Page<RuleNodeEntity> findAllRuleNodesByTypeAndVersionLessThan(@Param("ruleType") String ruleType,
|
||||||
@Param("version") int version,
|
@Param("version") int version,
|
||||||
@Param("searchText") String searchText,
|
@Param("searchText") String searchText,
|
||||||
|
|||||||
@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2016-2023 The Thingsboard Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.thingsboard.server.dao.sql.rule;
|
||||||
|
|
||||||
|
import com.datastax.oss.driver.api.core.uuid.Uuids;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
|
import org.thingsboard.server.common.data.id.RuleChainId;
|
||||||
|
import org.thingsboard.server.common.data.id.RuleNodeId;
|
||||||
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
|
import org.thingsboard.server.common.data.rule.RuleChain;
|
||||||
|
import org.thingsboard.server.common.data.rule.RuleNode;
|
||||||
|
import org.thingsboard.server.dao.AbstractJpaDaoTest;
|
||||||
|
import org.thingsboard.server.dao.rule.RuleChainDao;
|
||||||
|
import org.thingsboard.server.dao.rule.RuleNodeDao;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
|
public class JpaRuleNodeDaoTest extends AbstractJpaDaoTest {
|
||||||
|
|
||||||
|
public static final int COUNT = 40;
|
||||||
|
public static final String PREFIX_FOR_RULE_NODE_NAME = "SEARCH_TEXT_";
|
||||||
|
List<UUID> ruleNodeIds;
|
||||||
|
TenantId tenantId1;
|
||||||
|
TenantId tenantId2;
|
||||||
|
RuleChainId ruleChainId1;
|
||||||
|
RuleChainId ruleChainId2;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RuleChainDao ruleChainDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RuleNodeDao ruleNodeDao;
|
||||||
|
|
||||||
|
ListeningExecutorService executor;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
tenantId1 = TenantId.fromUUID(Uuids.timeBased());
|
||||||
|
ruleChainId1 = new RuleChainId(UUID.randomUUID());
|
||||||
|
tenantId2 = TenantId.fromUUID(Uuids.timeBased());
|
||||||
|
ruleChainId2 = new RuleChainId(UUID.randomUUID());
|
||||||
|
|
||||||
|
ruleNodeIds = createRuleNodes(tenantId1, tenantId2, ruleChainId1, ruleChainId2, COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
ruleNodeDao.removeAllByIds(ruleNodeIds);
|
||||||
|
if (executor != null) {
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveRuleName0x00_thenSomeDatabaseException() {
|
||||||
|
RuleNode ruleNode = getRuleNode(ruleChainId1, "T", "\u0000");
|
||||||
|
assertThatThrownBy(() -> ruleNodeIds.add(ruleNodeDao.save(tenantId1, ruleNode).getUuidId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindRuleNodesByTenantIdAndType() {
|
||||||
|
List<RuleNode> ruleNodes1 = ruleNodeDao.findRuleNodesByTenantIdAndType(tenantId1, "A", PREFIX_FOR_RULE_NODE_NAME);
|
||||||
|
assertEquals(20, ruleNodes1.size());
|
||||||
|
|
||||||
|
List<RuleNode> ruleNodes2 = ruleNodeDao.findRuleNodesByTenantIdAndType(tenantId2, "B", PREFIX_FOR_RULE_NODE_NAME);
|
||||||
|
assertEquals(20, ruleNodes2.size());
|
||||||
|
|
||||||
|
ruleNodes1 = ruleNodeDao.findRuleNodesByTenantIdAndType(tenantId1, "A", null);
|
||||||
|
assertEquals(20, ruleNodes1.size());
|
||||||
|
|
||||||
|
ruleNodes2 = ruleNodeDao.findRuleNodesByTenantIdAndType(tenantId2, "B", null);
|
||||||
|
assertEquals(20, ruleNodes2.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindRuleNodesByType() {
|
||||||
|
PageData<RuleNode> ruleNodes = ruleNodeDao.findAllRuleNodesByType( "A", new PageLink(10, 0, PREFIX_FOR_RULE_NODE_NAME));
|
||||||
|
assertEquals(20, ruleNodes.getTotalElements());
|
||||||
|
assertEquals(2, ruleNodes.getTotalPages());
|
||||||
|
assertEquals(10, ruleNodes.getData().size());
|
||||||
|
|
||||||
|
ruleNodes = ruleNodeDao.findAllRuleNodesByType( "A", new PageLink(10, 0));
|
||||||
|
assertEquals(20, ruleNodes.getTotalElements());
|
||||||
|
assertEquals(2, ruleNodes.getTotalPages());
|
||||||
|
assertEquals(10, ruleNodes.getData().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindRuleNodesByTypeAndVersionLessThan() {
|
||||||
|
PageData<RuleNode> ruleNodes = ruleNodeDao.findAllRuleNodesByTypeAndVersionLessThan( "A", 1, new PageLink(10, 0, PREFIX_FOR_RULE_NODE_NAME));
|
||||||
|
assertEquals(20, ruleNodes.getTotalElements());
|
||||||
|
assertEquals(2, ruleNodes.getTotalPages());
|
||||||
|
assertEquals(10, ruleNodes.getData().size());
|
||||||
|
|
||||||
|
ruleNodes = ruleNodeDao.findAllRuleNodesByTypeAndVersionLessThan( "A", 1, new PageLink(10, 0));
|
||||||
|
assertEquals(20, ruleNodes.getTotalElements());
|
||||||
|
assertEquals(2, ruleNodes.getTotalPages());
|
||||||
|
assertEquals(10, ruleNodes.getData().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<UUID> createRuleNodes(TenantId tenantId1, TenantId tenantId2, RuleChainId ruleChainId1, RuleChainId ruleChainId2, int count) {
|
||||||
|
var chain1 = new RuleChain(ruleChainId1);
|
||||||
|
chain1.setTenantId(tenantId1);
|
||||||
|
chain1.setName(ruleChainId1.toString());
|
||||||
|
ruleChainDao.save(tenantId1, chain1);
|
||||||
|
var chain2 = new RuleChain(ruleChainId2);
|
||||||
|
chain2.setTenantId(tenantId2);
|
||||||
|
chain2.setName(ruleChainId2.toString());
|
||||||
|
ruleChainDao.save(tenantId2, chain2);
|
||||||
|
List<UUID> savedRuleNodeIds = new ArrayList<>();
|
||||||
|
for (int i = 0; i < count / 2; i++) {
|
||||||
|
savedRuleNodeIds.add(ruleNodeDao.save(tenantId1, getRuleNode(ruleChainId1, "A", Integer.toString(i))).getUuidId());
|
||||||
|
savedRuleNodeIds.add(ruleNodeDao.save(tenantId2, getRuleNode(ruleChainId2, "B", Integer.toString(i + count / 2))).getUuidId());
|
||||||
|
}
|
||||||
|
return savedRuleNodeIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RuleNode getRuleNode(RuleChainId ruleChainId, String type, String nameSuffix) {
|
||||||
|
return getRuleNode(ruleChainId, Uuids.timeBased(), type, nameSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RuleNode getRuleNode(RuleChainId ruleChainId, UUID ruleNodeId, String type, String nameSuffix) {
|
||||||
|
RuleNode ruleNode = new RuleNode();
|
||||||
|
ruleNode.setId(new RuleNodeId(ruleNodeId));
|
||||||
|
ruleNode.setRuleChainId(ruleChainId);
|
||||||
|
ruleNode.setName(nameSuffix);
|
||||||
|
ruleNode.setType(type);
|
||||||
|
ruleNode.setConfiguration(JacksonUtil.newObjectNode().put("searchHint", PREFIX_FOR_RULE_NODE_NAME + nameSuffix));
|
||||||
|
ruleNode.setConfigurationVersion(0);
|
||||||
|
return ruleNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user