Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB equivalent of SQL expression '1=1' in Java

In SQL you can do the following;

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

How can I feed boolean expressions like '1=1' or '4<6' as criteria to MongoDB logical operators in Java?

For instance, I can do;

collection.find("$or",Arrays.asList(new Document("field1",value1),new Document("field2",value2)))

however, the above criteria are always based on already existing fields, while what I would like to do instead is more something like this (won't compile);

collection.find("$and",Arrays.asList(new Document(1,1),new Document("field2",value2)))

The reason I need this, is because I have a list of '$or' criteria but this list might be empty - in this case I want to have no criteria at all.


Update 1

While @gil.fernandes's solution is great for find queries, it will not work in aggregation queries (which is also what I need);

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'

Any ideas on how we can use the '1=1' logic in $match operators of aggregation?

Update 2

I applied @Veeram's second solution using mongo server version 3.4.7 However, if I include the addFields and match objects into my aggregation query I get 0 results. If I remove them, I get all the results.

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()
like image 764
arxakoulini Avatar asked Apr 09 '18 10:04

arxakoulini


People also ask

Which command in MongoDB is equivalent to SQL select?

An SQL SELECT statement typically retrieves data from tables in a database, much like a mongo shell find statement retrieves documents from a collection in a MongoDB database.

What is $$ in MongoDB?

The $map has parameters - input which specifies the array field name, as specifies the current array element identifier in an iteration, and in where each array element is processed in the iteration. Within the in , the current array element is referred using the $$ prefix - this is the syntax required.

How do I use $in in MongoDB?

Use the $in Operator to Match Values This query selects all documents in the inventory collection where the value of the quantity field is either 5 or 15. Although you can write this query using the $or operator, use the $in operator rather than the $or operator when performing equality checks on the same field.

What is equivalent command for where clause in MongoDB?

Use the $where operator to pass either a string containing a JavaScript expression or a full JavaScript function to the query system. The $where provides greater flexibility, but requires that the database processes the JavaScript expression or function for each document in the collection.


1 Answers

You can $expr on 3.6 mongo server version.

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;

Something like

Bson match = match(expr(new Document("$or", asList(new Document("$eq", asList(1, 1))))));
AggregateIterable aggregationQuery = collection.aggregate(asList(
                [...]
                match
));

This should output query something like

{ "$match" : { "$expr" : { "$or" : [{ "$eq" : [1, 1] }] } } }

For lower version 3.4 you can use combination of $addFields and $match to achieve the similar query.

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

This should output query something like

{ "$addFields" : { "cmp" : { "$or" : [{ "$eq" : [1, 1] }] } } }    
{ "$match" : { "cmp" : true } }
like image 74
s7vr Avatar answered Sep 25 '22 14:09

s7vr