如何使用查询对象比较 Spring 数据 MongoDB 中的 2 个字段
How to compare 2 fields in Spring Data MongoDB using query object
在简单 SQL 中看似自然的东西在 mongodb
中是不可能的。
给定一个简单的文档:
{
"total_units" : 100,
"purchased_unit" : 60
}
我想查询集合,使用 spring 数据条件 class,其中 "total_units > purchased_units"
。
据我了解,它应该与任何其他条件一样微不足道。
在 Spring api.
上找不到任何支持此内容的内容
我认为 Spring 数据 API 还不支持这一点,但您可能需要将 $where
查询包装在 Java 本机 DbObject 中。请注意,您的查询性能将受到相当大的影响,因为它会评估每条记录上的 Java 脚本代码,因此请尽可能结合索引查询。
本机Mongodb查询:
db.collection.find({ "$where": "this.total_units > this.purchased_units" });
本机Java查询:
DBObject obj = new BasicDBObject();
obj.put( "$where", "this.total_units > this.purchased_units");
一些considerations使用时必须要看的$where
:
Do not use global variables.
$where evaluates JavaScript and cannot take advantage of indexes.
Therefore, query performance improves when you express your query
using the standard MongoDB operators (e.g., $gt, $in). In general, you
should use $where only when you can’t express your query using another
operator. If you must use $where, try to include at least one other
standard query operator to filter the result set. Using $where alone
requires a table scan. Using normal non-$where query statements
provides the following performance advantages:
MongoDB will evaluate non-$where components of query before $where
statements. If the non-$where statements match no documents, MongoDB
will not perform any query evaluation using $where. The non-$where
query statements may use an index.
据我所知你做不到
query.addCriteria(Criteria.where("total_units").gt("purchased_units"));
但是会按照你的建议创建一个额外的计算字段说 computed_units
这是 total_units
和 purchased_units
之间的区别,然后你可以查询为:
Query query = new Query();
query.addCriteria(Criteria.where("computed_units").gt(0));
mongoOperation.find(query, CustomClass.class);
您可以使用以下模式:
Criteria criteria = new Criteria() {
@Override
public DBObject getCriteriaObject() {
DBObject obj = new BasicDBObject();
obj.put("$where", "this.total_units > this.purchased_units");
return obj;
}
};
Query query = Query.query(criteria);
感谢@Andrew Onischenko 历史性的好回答。
在 spring-data-mongodb(例如 2.1.9.RELEASE)的更新版本中,我必须编写如下相同的模式:
import org.bson.Document;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
// (...)
Criteria criteria = new Criteria() {
@Override
public Document getCriteriaObject() {
Document doc = new Document();
doc.put("$where", "this.total_units > this.purchased_units");
return doc;
}
};
Query query = Query.query(criteria);
一种方法是这样的:
Criteria c = Criteria.where("total_units").gt("$purchased_unit");
AggregationOperation matchOperation = Aggregation.match(c);
Aggregation aggregation = Aggregation.newAggregation(matchOperation);
mongoTemplate.aggregate(aggregation, "collectionNameInStringOnly", ReturnTypeEntity.class);
记得将集合名称放在字符串中,以便将标准中提到的字段的拼写与数据库集合中的字段相匹配。
在简单 SQL 中看似自然的东西在 mongodb
中是不可能的。
给定一个简单的文档:
{
"total_units" : 100,
"purchased_unit" : 60
}
我想查询集合,使用 spring 数据条件 class,其中 "total_units > purchased_units"
。
据我了解,它应该与任何其他条件一样微不足道。
在 Spring api.
上找不到任何支持此内容的内容我认为 Spring 数据 API 还不支持这一点,但您可能需要将 $where
查询包装在 Java 本机 DbObject 中。请注意,您的查询性能将受到相当大的影响,因为它会评估每条记录上的 Java 脚本代码,因此请尽可能结合索引查询。
本机Mongodb查询:
db.collection.find({ "$where": "this.total_units > this.purchased_units" });
本机Java查询:
DBObject obj = new BasicDBObject();
obj.put( "$where", "this.total_units > this.purchased_units");
一些considerations使用时必须要看的$where
:
Do not use global variables.
$where evaluates JavaScript and cannot take advantage of indexes. Therefore, query performance improves when you express your query using the standard MongoDB operators (e.g., $gt, $in). In general, you should use $where only when you can’t express your query using another operator. If you must use $where, try to include at least one other standard query operator to filter the result set. Using $where alone requires a table scan. Using normal non-$where query statements provides the following performance advantages:
MongoDB will evaluate non-$where components of query before $where statements. If the non-$where statements match no documents, MongoDB will not perform any query evaluation using $where. The non-$where query statements may use an index.
据我所知你做不到
query.addCriteria(Criteria.where("total_units").gt("purchased_units"));
但是会按照你的建议创建一个额外的计算字段说 computed_units
这是 total_units
和 purchased_units
之间的区别,然后你可以查询为:
Query query = new Query();
query.addCriteria(Criteria.where("computed_units").gt(0));
mongoOperation.find(query, CustomClass.class);
您可以使用以下模式:
Criteria criteria = new Criteria() {
@Override
public DBObject getCriteriaObject() {
DBObject obj = new BasicDBObject();
obj.put("$where", "this.total_units > this.purchased_units");
return obj;
}
};
Query query = Query.query(criteria);
感谢@Andrew Onischenko 历史性的好回答。
在 spring-data-mongodb(例如 2.1.9.RELEASE)的更新版本中,我必须编写如下相同的模式:
import org.bson.Document;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
// (...)
Criteria criteria = new Criteria() {
@Override
public Document getCriteriaObject() {
Document doc = new Document();
doc.put("$where", "this.total_units > this.purchased_units");
return doc;
}
};
Query query = Query.query(criteria);
一种方法是这样的:
Criteria c = Criteria.where("total_units").gt("$purchased_unit");
AggregationOperation matchOperation = Aggregation.match(c);
Aggregation aggregation = Aggregation.newAggregation(matchOperation);
mongoTemplate.aggregate(aggregation, "collectionNameInStringOnly", ReturnTypeEntity.class);
记得将集合名称放在字符串中,以便将标准中提到的字段的拼写与数据库集合中的字段相匹配。