MongoDB相当于Java中的SQL表达式"1=1"



在SQL中,你可以执行以下操作;

SELECT * FROM CUSTOMERS WHERE ID=43 AND 1=1

如何在 Java 中将"1=1"或"4<6"等布尔表达式作为标准提供给 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: 命令失败,出现错误 16395:"$where 是 不允许在$match聚合表达式内

"

关于我们如何在聚合运算符中使用"1=1"逻辑$match有什么想法吗?

更新 2

我使用 mongo 服务器版本 3.4.7 应用了@Veeram的第二个解决方案 但是,如果我将addFieldsmatch对象包含在聚合查询中,则得到 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()

您可以在 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 } }

在普通的MongoDB Javascript查询中,你可以用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" }]});

注意:这实际上返回集合中的所有记录。

更新 2

实际上,$or子句与$where的组合也可以在Java中完成,也可以进行简单组合。下面是一个示例:

// 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);
}

这是我的完整测试类供参考:

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>

相关内容

  • 没有找到相关文章

最新更新