From 52bfd78174495b852c2539fb6bcd3387d6b0de58 Mon Sep 17 00:00:00 2001 From: dashevchenko Date: Tue, 22 Jul 2025 17:35:24 +0300 Subject: [PATCH] fixed filter implementation for numeric entity field saved as str --- .../server/edqs/data/dp/StringDataPoint.java | 10 ++++++++ .../edqs/repo/EntityTypeFilterTest.java | 23 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/common/edqs/src/main/java/org/thingsboard/server/edqs/data/dp/StringDataPoint.java b/common/edqs/src/main/java/org/thingsboard/server/edqs/data/dp/StringDataPoint.java index 52205e2f72..6c67b467eb 100644 --- a/common/edqs/src/main/java/org/thingsboard/server/edqs/data/dp/StringDataPoint.java +++ b/common/edqs/src/main/java/org/thingsboard/server/edqs/data/dp/StringDataPoint.java @@ -33,6 +33,16 @@ public class StringDataPoint extends AbstractDataPoint { this.value = deduplicate ? TbStringPool.intern(value) : value; } + @Override + public double getDouble() { + return Double.parseDouble(value); + } + + @Override + public long getLong() { + return Long.parseLong(value); + } + @Override public DataType getType() { return DataType.STRING; diff --git a/edqs/src/test/java/org/thingsboard/server/edqs/repo/EntityTypeFilterTest.java b/edqs/src/test/java/org/thingsboard/server/edqs/repo/EntityTypeFilterTest.java index 8fab142dc7..e7fc4419ef 100644 --- a/edqs/src/test/java/org/thingsboard/server/edqs/repo/EntityTypeFilterTest.java +++ b/edqs/src/test/java/org/thingsboard/server/edqs/repo/EntityTypeFilterTest.java @@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.kv.BasicTsKvEntry; import org.thingsboard.server.common.data.kv.BooleanDataEntry; +import org.thingsboard.server.common.data.kv.DoubleDataEntry; import org.thingsboard.server.common.data.kv.StringDataEntry; import org.thingsboard.server.common.data.query.EntityDataPageLink; import org.thingsboard.server.common.data.query.EntityDataQuery; @@ -36,7 +37,9 @@ import org.thingsboard.server.common.data.query.EntityKeyValueType; import org.thingsboard.server.common.data.query.EntityTypeFilter; import org.thingsboard.server.common.data.query.FilterPredicateValue; import org.thingsboard.server.common.data.query.KeyFilter; +import org.thingsboard.server.common.data.query.NumericFilterPredicate; import org.thingsboard.server.common.data.query.StringFilterPredicate; +import org.thingsboard.server.edqs.util.RepositoryUtils; import java.util.Arrays; import java.util.List; @@ -61,6 +64,10 @@ public class EntityTypeFilterTest extends AbstractEDQTest { addOrUpdate(new LatestTsKv(device.getId(), new BasicTsKvEntry(43, new StringDataEntry("state", "enabled")), 0L)); addOrUpdate(new LatestTsKv(device2.getId(), new BasicTsKvEntry(43, new StringDataEntry("state", "disabled")), 0L)); addOrUpdate(new LatestTsKv(device3.getId(), new BasicTsKvEntry(43, new BooleanDataEntry("free", true)), 0L)); + + addOrUpdate(new LatestTsKv(device.getId(), new BasicTsKvEntry(43, new StringDataEntry("temperature", "26.0")), 0L)); + addOrUpdate(new LatestTsKv(device2.getId(), new BasicTsKvEntry(43, new DoubleDataEntry("temperature", 25.0)), 0L)); + addOrUpdate(new LatestTsKv(device3.getId(), new BasicTsKvEntry(43, new DoubleDataEntry("temperature", 19.0)), 0L)); } @After @@ -87,6 +94,11 @@ public class EntityTypeFilterTest extends AbstractEDQTest { // find asset entities result = repository.findEntityDataByQuery(tenantId, null, getEntityTypeQuery(EntityType.ASSET, null), false); Assert.assertEquals(0, result.getTotalElements()); + + // find all tenant devices with filter by temperature + KeyFilter tempFilter = getTemperatureFilter(NumericFilterPredicate.NumericOperation.GREATER_OR_EQUAL, 20.0); + result = repository.findEntityDataByQuery(tenantId, null, getEntityTypeQuery(EntityType.DEVICE, List.of(tempFilter)), false); + Assert.assertEquals(2, result.getTotalElements()); } @Test @@ -143,4 +155,15 @@ public class EntityTypeFilterTest extends AbstractEDQTest { return nameFilter; } + private static KeyFilter getTemperatureFilter(NumericFilterPredicate.NumericOperation operation, Double predicateValue) { + KeyFilter tempFilter = new KeyFilter(); + tempFilter.setKey(new EntityKey(EntityKeyType.TIME_SERIES, "temperature")); + var predicate = new NumericFilterPredicate(); + predicate.setOperation(operation); + predicate.setValue(new FilterPredicateValue<>(predicateValue)); + tempFilter.setPredicate(predicate); + tempFilter.setValueType(EntityKeyValueType.NUMERIC); + return tempFilter; + } + }