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 的第二个解决方案 但是,如果我将 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()

在正常的 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 } }