MongoDB 等价于 SQL 表达式 '1=1' in Java
MongoDB equivalent of SQL expression '1=1' in Java
在 SQL 中,您可以执行以下操作;
SELECT * FROM CUSTOMERS WHERE ID=43 AND 1=1
如何将布尔表达式(如“1=1”或“4<6”)作为条件提供给 Java 中的 MongoDB 逻辑运算符?
例如,我可以做到;
collection.find("$or",Arrays.asList(new Document("field1",value1),new Document("field2",value2)))
然而,上述标准总是基于已经存在的字段,而我想做的更像是这样的(不会编译);
collection.find("$and",Arrays.asList(new Document(1,1),new Document("field2",value2)))
我需要这个的原因是因为我有一个“$or”标准列表,但这个列表可能是空的 - 在这种情况下我根本不想有任何标准。
更新 1
虽然@gil.fernandes的解决方案非常适合find
查询,但它不适用于聚合查询(这也是我需要的) ;
AggregateIterable aggregationQuery = collection.aggregate(Arrays.asList(
[...]
new Document("$match", new Document("$or", Arrays.asList(new Document("$where","1==1"))))
));
MongoCommandException: Command failed with error 16395: '$where is
not allowed inside of a $match aggregation expression'
关于如何在 $match 聚合运算符中使用“1=1”逻辑有什么想法吗?
更新 2
我使用 mongo 服务器版本 3.4.7 应用了@Veeram 的第二个解决方案
但是,如果我将 addFields
和 match
对象包含到我的聚合查询中,我会得到 0 个结果。
如果我删除它们,我会得到所有结果。
collection = mongoClient.getDatabase("testDatabase").getCollection("testColletion");
collection.insertOne(new Document("testField","testValue"));
Bson addFields = Aggregates.addFields(new Field<>("cmp", new Document("$or", Arrays.asList(new Document("$eq", Arrays.asList(1, 1))))));
Bson match = Aggregates.match(Filters.eq("cmp", 1));
AggregateIterable aggregationQuery = collection.aggregate(Arrays.asList(
new Document("$match", new Document("testField", "testValue")),
addFields,
match
));
boolean hasDocuments = aggregationQuery.iterator().hasNext()
在正常的 MongoDB Java 脚本查询中,您可以使用 1=1
.
表达过滤器
这是一个例子:
db.customer.find(
{"customer.id" : "1081965259", "customer.status": "Live", "$where": "1 == 1"},
{"customer.id": 1, "customer.status": 1})
.pretty();
相关查询为"$where": "1 == 1"
。如果您将此设置为 "$where": "1 == 2"
,则永远不会检索任何结果。
更新
您也可以在 or 语句中使用此子句:
db.customer.find({"$or": [{ "customer.id" : "1081959342" }, { "$where": "1 == 1" }]});
注意:这 returns 字面上是集合中的所有记录。
更新 2
实际上 $or
子句与 $where
的组合也可以在 Java 中完成,就像简单的 and 组合一样。这是一个例子:
// Or Logic
private static FindIterable<Document> findDocumentByKeysOrClause(String id, MongoCollection<Document> collection) {
BasicDBObject query = new BasicDBObject();
List<BasicDBObject> orQueryList =
Arrays.asList(new BasicDBObject("customer.customerId.sourceKeys.keies.id", id),
new BasicDBObject("$where", "1 == 1"));
query.put("$or", orQueryList);
return collection.find(query);
}
这是我的完整测试class供参考:
import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import org.bson.types.ObjectId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Tests Mongo custom queries.
*/
public class MongoClauseTester {
public static void main(String[] args) {
MongoClient mongoClient = new MongoClient("localhost", 27017);
MongoDatabase db = mongoClient.getDatabase("customers");
MongoCollection<Document> customerCollection = db.getCollection("customer_UK");
final FindIterable<Document> documentByKeysOrClause = findDocumentByKeysOrClause("C@0248870263@DHUB", customerCollection);
MongoCursor<Document> iter = documentByKeysOrClause.iterator();
for(int i = 0; i < 3 && iter.hasNext(); i++) {
System.out.println(iter.next().toJson());
}
}
// And logic
private static FindIterable<Document> findDocumentByKeys(String id, MongoCollection<Document> collection) {
BasicDBObject query = new BasicDBObject();
query.put("customer.customerId.sourceKeys.keies.id", id);
query.put("$where", "1 == 1");
return collection.find(query);
}
// Or Logic
private static FindIterable<Document> findDocumentByKeysOrClause(String id, MongoCollection<Document> collection) {
BasicDBObject query = new BasicDBObject();
List<BasicDBObject> orQueryList =
Arrays.asList(new BasicDBObject("customer.customerId.sourceKeys.keies.id", id),
new BasicDBObject("$where", "1 == 1"));
query.put("$or", orQueryList);
return collection.find(query);
}
}
这是使用的 MongoDB 驱动程序的版本:
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.4.1</version>
</dependency>
您可以在 3.6 mongo 服务器版本上 $expr
。
import static com.mongodb.client.model.Aggregates.addFields;
import static com.mongodb.client.model.Aggregates.match;
import static com.mongodb.client.model.Filters.*;
import static java.util.Arrays.asList;
类似
Bson match = match(expr(new Document("$or", asList(new Document("$eq", asList(1, 1))))));
AggregateIterable aggregationQuery = collection.aggregate(asList(
[...]
match
));
这应该输出类似于
的查询
{ "$match" : { "$expr" : { "$or" : [{ "$eq" : [1, 1] }] } } }
对于3.4以下的版本,您可以使用$addFields
和$match
的组合来实现类似的查询。
Bson addFields = addFields(new Field<>("cmp", new Document("$or", asList(new Document("$eq", asList(1, 1))))));
Bson match = match(eq("cmp", true));
AggregateIterable aggregationQuery = collection.aggregate(asList(
[...]
addFields,
match
));
这应该输出类似于
的查询
{ "$addFields" : { "cmp" : { "$or" : [{ "$eq" : [1, 1] }] } } }
{ "$match" : { "cmp" : true } }
在 SQL 中,您可以执行以下操作;
SELECT * FROM CUSTOMERS WHERE ID=43 AND 1=1
如何将布尔表达式(如“1=1”或“4<6”)作为条件提供给 Java 中的 MongoDB 逻辑运算符?
例如,我可以做到;
collection.find("$or",Arrays.asList(new Document("field1",value1),new Document("field2",value2)))
然而,上述标准总是基于已经存在的字段,而我想做的更像是这样的(不会编译);
collection.find("$and",Arrays.asList(new Document(1,1),new Document("field2",value2)))
我需要这个的原因是因为我有一个“$or”标准列表,但这个列表可能是空的 - 在这种情况下我根本不想有任何标准。
更新 1
虽然@gil.fernandes的解决方案非常适合find
查询,但它不适用于聚合查询(这也是我需要的) ;
AggregateIterable aggregationQuery = collection.aggregate(Arrays.asList(
[...]
new Document("$match", new Document("$or", Arrays.asList(new Document("$where","1==1"))))
));
MongoCommandException: Command failed with error 16395: '$where is not allowed inside of a $match aggregation expression'
关于如何在 $match 聚合运算符中使用“1=1”逻辑有什么想法吗?
更新 2
我使用 mongo 服务器版本 3.4.7 应用了@Veeram 的第二个解决方案
但是,如果我将 addFields
和 match
对象包含到我的聚合查询中,我会得到 0 个结果。
如果我删除它们,我会得到所有结果。
collection = mongoClient.getDatabase("testDatabase").getCollection("testColletion");
collection.insertOne(new Document("testField","testValue"));
Bson addFields = Aggregates.addFields(new Field<>("cmp", new Document("$or", Arrays.asList(new Document("$eq", Arrays.asList(1, 1))))));
Bson match = Aggregates.match(Filters.eq("cmp", 1));
AggregateIterable aggregationQuery = collection.aggregate(Arrays.asList(
new Document("$match", new Document("testField", "testValue")),
addFields,
match
));
boolean hasDocuments = aggregationQuery.iterator().hasNext()
在正常的 MongoDB Java 脚本查询中,您可以使用 1=1
.
这是一个例子:
db.customer.find(
{"customer.id" : "1081965259", "customer.status": "Live", "$where": "1 == 1"},
{"customer.id": 1, "customer.status": 1})
.pretty();
相关查询为"$where": "1 == 1"
。如果您将此设置为 "$where": "1 == 2"
,则永远不会检索任何结果。
更新
您也可以在 or 语句中使用此子句:
db.customer.find({"$or": [{ "customer.id" : "1081959342" }, { "$where": "1 == 1" }]});
注意:这 returns 字面上是集合中的所有记录。
更新 2
实际上 $or
子句与 $where
的组合也可以在 Java 中完成,就像简单的 and 组合一样。这是一个例子:
// Or Logic
private static FindIterable<Document> findDocumentByKeysOrClause(String id, MongoCollection<Document> collection) {
BasicDBObject query = new BasicDBObject();
List<BasicDBObject> orQueryList =
Arrays.asList(new BasicDBObject("customer.customerId.sourceKeys.keies.id", id),
new BasicDBObject("$where", "1 == 1"));
query.put("$or", orQueryList);
return collection.find(query);
}
这是我的完整测试class供参考:
import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import org.bson.types.ObjectId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Tests Mongo custom queries.
*/
public class MongoClauseTester {
public static void main(String[] args) {
MongoClient mongoClient = new MongoClient("localhost", 27017);
MongoDatabase db = mongoClient.getDatabase("customers");
MongoCollection<Document> customerCollection = db.getCollection("customer_UK");
final FindIterable<Document> documentByKeysOrClause = findDocumentByKeysOrClause("C@0248870263@DHUB", customerCollection);
MongoCursor<Document> iter = documentByKeysOrClause.iterator();
for(int i = 0; i < 3 && iter.hasNext(); i++) {
System.out.println(iter.next().toJson());
}
}
// And logic
private static FindIterable<Document> findDocumentByKeys(String id, MongoCollection<Document> collection) {
BasicDBObject query = new BasicDBObject();
query.put("customer.customerId.sourceKeys.keies.id", id);
query.put("$where", "1 == 1");
return collection.find(query);
}
// Or Logic
private static FindIterable<Document> findDocumentByKeysOrClause(String id, MongoCollection<Document> collection) {
BasicDBObject query = new BasicDBObject();
List<BasicDBObject> orQueryList =
Arrays.asList(new BasicDBObject("customer.customerId.sourceKeys.keies.id", id),
new BasicDBObject("$where", "1 == 1"));
query.put("$or", orQueryList);
return collection.find(query);
}
}
这是使用的 MongoDB 驱动程序的版本:
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.4.1</version>
</dependency>
您可以在 3.6 mongo 服务器版本上 $expr
。
import static com.mongodb.client.model.Aggregates.addFields;
import static com.mongodb.client.model.Aggregates.match;
import static com.mongodb.client.model.Filters.*;
import static java.util.Arrays.asList;
类似
Bson match = match(expr(new Document("$or", asList(new Document("$eq", asList(1, 1))))));
AggregateIterable aggregationQuery = collection.aggregate(asList(
[...]
match
));
这应该输出类似于
的查询{ "$match" : { "$expr" : { "$or" : [{ "$eq" : [1, 1] }] } } }
对于3.4以下的版本,您可以使用$addFields
和$match
的组合来实现类似的查询。
Bson addFields = addFields(new Field<>("cmp", new Document("$or", asList(new Document("$eq", asList(1, 1))))));
Bson match = match(eq("cmp", true));
AggregateIterable aggregationQuery = collection.aggregate(asList(
[...]
addFields,
match
));
这应该输出类似于
的查询{ "$addFields" : { "cmp" : { "$or" : [{ "$eq" : [1, 1] }] } } }
{ "$match" : { "cmp" : true } }