Java 根据字段的存在,使用MongoDB中的Spring投射一个布尔值
我需要根据MongoDB with Spring Framework中文档中某个字段的存在情况投射一个布尔值 假设我的Mongo数据库中有文档。它们的结构如下所示(testedField可能不存在): 或者像这样:Java 根据字段的存在,使用MongoDB中的Spring投射一个布尔值,java,spring,mongodb,Java,Spring,Mongodb,我需要根据MongoDB with Spring Framework中文档中某个字段的存在情况投射一个布尔值 假设我的Mongo数据库中有文档。它们的结构如下所示(testedField可能不存在): 或者像这样: { "_id": ObjectId("some object ID"), "field1": "some value", "field2": "another value" } 我还有一个数据类MyClass: @AllArgsConstructor @Ge
{
"_id": ObjectId("some object ID"),
"field1": "some value",
"field2": "another value"
}
我还有一个数据类MyClass:
@AllArgsConstructor
@Getter
public class MyClass {
private String field1;
private String field2;
private boolean myBoolVal;
}
在我的DAO中,有一个方法将其字段的值投影到类:
public List<MyClass> findThings(Collection<ObjectId> ids) {
Criteria criteria = where(ID).in(ids);
Aggregation matchAndProject = newAggregation(
match(criteria),
project("field1", "field2")
.and("testedField").ne(null).as("myBoolVal"));
return mongoTemplate.aggregate(matchAndProject, "my_collection", MyClass.class).getMappedResults();
}
公共列表查找内容(集合ID){
标准=其中(ID).in(ID);
聚合匹配项目=newAggregation(
匹配(标准),
项目(“现场1”、“现场2”)
。和(“testedField”).ne(null).as(“myBoolVal”);
返回mongoTemplate.aggregate(matchAndProject,“我的收藏”,MyClass.class).getMappedResults();
}
如果testedField存在,则在myBoolVal字段中设置true
,如果不存在,则在false
字段中设置
但是上面的代码抛出了IllegalArgumentException(“值不能为null!”)
有办法让它工作吗?为什么不
Boolean
true
如果字段存在,false
和null
如果不存在
但是在您的例子中,字段myBoolVal
任何内容都等于false
。有一件事-你的场是最终的,你不能对它们进行任何操作。。。将实体字段设置为final
是不正确的
最后一件事:你用弹簧吗?它有一个用于mongodb的完美库,使用mongodb与jpa功能非常相似。使用条件投影
public List<MyClass> findThings(Collection<ObjectId> ids) {
Cond condition = ConditionalOperators.when(Criteria.where("testedField")
.exists(true))
.then(true)
.otherwise(false)
;
Criteria criteria = where(ID).in(ids);
Aggregation matchAndProject = newAggregation(
match(criteria),
project("field1", "field2")
and(condition).as("myBoolVal"));
return mongoTemplate.aggregate(matchAndProject, "my_collection", MyClass.class).getMappedResults();
}
公共列表查找内容(集合ID){
Cond condition=条件运算符.when(条件.where(“testedField”)
.存在(真实))
.那么(对)
。否则(错)
;
标准=其中(ID).in(ID);
聚合匹配项目=newAggregation(
匹配(标准),
项目(“现场1”、“现场2”)
和(条件)。如(“myBoolVal”);
返回mongoTemplate.aggregate(matchAndProject,“我的收藏”,MyClass.class).getMappedResults();
}
我找到了解决方案:只要在不存在的情况下(“字段名”)
使用就足够了(
或为(null)
等
public List<MyClass> findThings(Collection<ObjectId> ids) {
Criteria criteria = where(ID).in(ids);
Aggregation matchAndProject = newAggregation(
match(criteria),
project("field1", "field2")
.and(ConditionalOperators.when("testedField")
.then(true)
.otherwise(false))
.as("myBoolVal"));
return mongoTemplate.aggregate(matchAndProject, "my_collection", MyClass.class).getMappedResults();
}
公共列表查找内容(集合ID){
标准=其中(ID).in(ID);
聚合匹配项目=newAggregation(
匹配(标准),
项目(“现场1”、“现场2”)
.和(条件运算符。何时(“测试字段”)
.那么(对)
。否则(错误))
.as(“myBoolVal”);
返回mongoTemplate.aggregate(matchAndProject,“我的收藏”,MyClass.class).getMappedResults();
}
问题在于聚合本身:它不允许在ne()
方法中使用null
。这些方法来自Spring的org.springframework.data.mongodb.core
包。在这种情况下,为什么您的实体类没有用@Document
,@Field
,no@Id
注释?如果要处理实体之类的对象,请将其替换为实体),好的,但这仍然无法解决问题。它最终导致:com.mongodb.MongoCommandException:Command失败,错误为168(InvalidPipelineOperator):“无法识别的表达式“$exists”
替换此代码并尝试Cond condition=ConditionalOperators.when(Criteria.where(“testedField”)。为(null))。然后为(false)。否则为(true);两个答案之间有很大的区别,如果你更加注意的话,这些答案可以让你在不使用MongoCommandException的情况下使用查询。方法exists()
导致上述异常,因此应避免使用它。这是你所指答案的评论部分。
public List<MyClass> findThings(Collection<ObjectId> ids) {
Criteria criteria = where(ID).in(ids);
Aggregation matchAndProject = newAggregation(
match(criteria),
project("field1", "field2")
.and(ConditionalOperators.when("testedField")
.then(true)
.otherwise(false))
.as("myBoolVal"));
return mongoTemplate.aggregate(matchAndProject, "my_collection", MyClass.class).getMappedResults();
}