Spring 数据 MongoDB,按 long 值搜索
Spring Data MongoDB, Searching by long value
我在 mongo 中存储了一个对象,如下所示(当我查看文档时,它在 RoboMongo 中的显示方式):
{
"_id": ObjectId("5e579c8674f69d1c1451f3ae"),
...
"timestamp": NumberLong(1582800002779),
...
"_class": "regular"
}
我存储的对象是这样定义的:
public class MyObjectModel {
@Id
@Field(value = ID_FIELD_NAME)
private String id;
@Field(value = TIMESTAMP_FIELD_NAME)
private Long timestamp;
...
}
我的意图是获取时间范围内的对象列表。
这就是我使用 spring 数据 mongo db:
创建查询的方式
public List<Criteria> generateAllCriteria() {
List<Criteria> criteriaList = new ArrayList<>();
Optional.ofNullable(searchCriteria.getFromTimestamp()).map(ts -> criteriaList.add(generateFromTimestampCriteria(ts)));
Optional.ofNullable(searchCriteria.getToTimestamp()).map(ts -> criteriaList.add(generateToTimestampCriteria(ts)));
return criteriaList;
}
private Criteria generateFromTimestampCriteria(Long fromTimestamp) {
Criteria critFromTimestamp = Criteria.where(TIMESTAMP_FIELD_NAME).gte(fromTimestamp);
log.debug("From Timestamp criteria {}", critFromTimestamp.getCriteriaObject().toJson());
return critFromTimestamp;
}
private Criteria generateToTimestampCriteria(Long toTimestamp) {
Criteria critToTimestamp = Criteria.where(TIMESTAMP_FIELD_NAME).lt(toTimestamp);
log.debug("To Timestamp criteria {}", critToTimestamp.getCriteriaObject().toJson());
return critToTimestamp;
}
...
List<Criteria> criteriaList = generateAllCriteria();
Criteria finalCriteria = new Criteria();
finalCriteria = finalCriteria.andOperator(criteriaList.toArray(new Criteria[criteriaList.size()]));
log.debug("Final criteria {}", finalCriteria);
Query query = new Query();
query.addCriteria(finalCriteria);
List<MyObjectModel> myObjects = mongoTemplate.find(query, MyObjectModel.class);
我显示它们时的查询如下:
From Timestamp criteria { "timestamp" : { "$gte" : { "$numberLong" : "1582714365857" } } }
To Timestamp criteria { "timestamp" : { "$lt" : { "$numberLong" : "1582887165858" } } }
最后的查询条件好像是这样的:
o.s.data.mongodb.core.MongoTemplate - find using query: { "$and" : [{ "timestamp" : { "$gte" : { "$numberLong" : "1582714365857" } } }, { "timestamp" : { "$lt" : { "$numberLong" : "1582887165858" } } }] } fields: Document{{}} for class: class mypackage.model.MyObjectModel in collection: myObjectModel
乍一看似乎没问题,但是当我手动 运行 它反对 Mongo 它没有 return 任何记录,在我看来这意味着它在某种程度上是不正确的.
这正是我 运行 在 Mongo:
db.getCollection('my-collection').find({ "$and" : [{ "timestamp" : { "$gte" : { "$numberLong" : "1582707873806" } } }, { "timestamp" : { "$lt" : { "$numberLong" : "1582887165858" } } }] })
而且它显然没有return任何记录。但是当我修改查询并摆脱 $numberLong:
db.getCollection('my-collection').find({ "$and" : [{ "timestamp" : { "$gte" : 1582707873806 } }, { "timestamp" : { "$lt" : 1582887165858 } }] })
它就像一个魅力。
有人可以启发我并解释我做错了什么吗?应该如何以正确的方式完成?
如何制作 spring 数据 mongo 以创建正确的查询?
不用说字符串和整数工作得很好。大约只有 LONGs.
提前感谢您的帮助。
据我了解:
- from/to 是查询中唯一的参数
- 两者都可以为空
并假设您的模型是:
public class Regular {
@Id
private String id;
@Field
private Long timestamp;
}
那么可能的解决方案(恕我直言,更短)是:
// exists(true) is a "hack" to return the elements in case both from/to are null
public List<Regular> find(Long from, Long to) {
var criteria = where("timestamp").exists(true);
if(from != null) {
criteria.gte(from);
}
if(to != null) {
criteria.lte(to);
}
return mongoTemplate.find(Query.query(criteria), Regular.class);
}
PS。我用 Spring Boot 2.2.4 和 Mongo 3.6.
检查过它
PS2。您仍然可以通过额外的 if 条件处理 from/to 均为 null 的情况,然后删除 exists(true)。
我找到了我遇到的同样问题的解决方案。
我刚刚创建了一个自定义读取转换器,当我从数据库中获取数据时,它将 DATE 值映射到 long 值。
这是我参考的 link
enter link description here
我在 mongo 中存储了一个对象,如下所示(当我查看文档时,它在 RoboMongo 中的显示方式):
{
"_id": ObjectId("5e579c8674f69d1c1451f3ae"),
...
"timestamp": NumberLong(1582800002779),
...
"_class": "regular"
}
我存储的对象是这样定义的:
public class MyObjectModel {
@Id
@Field(value = ID_FIELD_NAME)
private String id;
@Field(value = TIMESTAMP_FIELD_NAME)
private Long timestamp;
...
}
我的意图是获取时间范围内的对象列表。 这就是我使用 spring 数据 mongo db:
创建查询的方式 public List<Criteria> generateAllCriteria() {
List<Criteria> criteriaList = new ArrayList<>();
Optional.ofNullable(searchCriteria.getFromTimestamp()).map(ts -> criteriaList.add(generateFromTimestampCriteria(ts)));
Optional.ofNullable(searchCriteria.getToTimestamp()).map(ts -> criteriaList.add(generateToTimestampCriteria(ts)));
return criteriaList;
}
private Criteria generateFromTimestampCriteria(Long fromTimestamp) {
Criteria critFromTimestamp = Criteria.where(TIMESTAMP_FIELD_NAME).gte(fromTimestamp);
log.debug("From Timestamp criteria {}", critFromTimestamp.getCriteriaObject().toJson());
return critFromTimestamp;
}
private Criteria generateToTimestampCriteria(Long toTimestamp) {
Criteria critToTimestamp = Criteria.where(TIMESTAMP_FIELD_NAME).lt(toTimestamp);
log.debug("To Timestamp criteria {}", critToTimestamp.getCriteriaObject().toJson());
return critToTimestamp;
}
...
List<Criteria> criteriaList = generateAllCriteria();
Criteria finalCriteria = new Criteria();
finalCriteria = finalCriteria.andOperator(criteriaList.toArray(new Criteria[criteriaList.size()]));
log.debug("Final criteria {}", finalCriteria);
Query query = new Query();
query.addCriteria(finalCriteria);
List<MyObjectModel> myObjects = mongoTemplate.find(query, MyObjectModel.class);
我显示它们时的查询如下:
From Timestamp criteria { "timestamp" : { "$gte" : { "$numberLong" : "1582714365857" } } }
To Timestamp criteria { "timestamp" : { "$lt" : { "$numberLong" : "1582887165858" } } }
最后的查询条件好像是这样的:
o.s.data.mongodb.core.MongoTemplate - find using query: { "$and" : [{ "timestamp" : { "$gte" : { "$numberLong" : "1582714365857" } } }, { "timestamp" : { "$lt" : { "$numberLong" : "1582887165858" } } }] } fields: Document{{}} for class: class mypackage.model.MyObjectModel in collection: myObjectModel
乍一看似乎没问题,但是当我手动 运行 它反对 Mongo 它没有 return 任何记录,在我看来这意味着它在某种程度上是不正确的. 这正是我 运行 在 Mongo:
db.getCollection('my-collection').find({ "$and" : [{ "timestamp" : { "$gte" : { "$numberLong" : "1582707873806" } } }, { "timestamp" : { "$lt" : { "$numberLong" : "1582887165858" } } }] })
而且它显然没有return任何记录。但是当我修改查询并摆脱 $numberLong:
db.getCollection('my-collection').find({ "$and" : [{ "timestamp" : { "$gte" : 1582707873806 } }, { "timestamp" : { "$lt" : 1582887165858 } }] })
它就像一个魅力。
有人可以启发我并解释我做错了什么吗?应该如何以正确的方式完成? 如何制作 spring 数据 mongo 以创建正确的查询?
不用说字符串和整数工作得很好。大约只有 LONGs.
提前感谢您的帮助。
据我了解:
- from/to 是查询中唯一的参数
- 两者都可以为空
并假设您的模型是:
public class Regular {
@Id
private String id;
@Field
private Long timestamp;
}
那么可能的解决方案(恕我直言,更短)是:
// exists(true) is a "hack" to return the elements in case both from/to are null
public List<Regular> find(Long from, Long to) {
var criteria = where("timestamp").exists(true);
if(from != null) {
criteria.gte(from);
}
if(to != null) {
criteria.lte(to);
}
return mongoTemplate.find(Query.query(criteria), Regular.class);
}
PS。我用 Spring Boot 2.2.4 和 Mongo 3.6.
检查过它PS2。您仍然可以通过额外的 if 条件处理 from/to 均为 null 的情况,然后删除 exists(true)。
我找到了我遇到的同样问题的解决方案。 我刚刚创建了一个自定义读取转换器,当我从数据库中获取数据时,它将 DATE 值映射到 long 值。 这是我参考的 link enter link description here