How to execute mongo query from spring's mongo template? - java

I am trying to execute queries like "db.post.find().pretty()" from executeCommand of mongoTemplete of spring framework. But I am unable to do it?Is there a way to execute queries like above directly from mongotempelate? Any help is appreciated.
Here is my code:
public CommandResult getMongoReportResult(){
CommandResult result=mongoTemplate.executeCommand("{$and:[{\"by\":\"tutorials point\"},{\"title\": \"MongoDB Overview\"}]}");
return result;
}

yes of course, but you should pass a BasicDBObject as parameter, and not a String, like this:
(and your command wasn't formatted correctly, see find command
BasicDBList andList = new BasicDBList();
andList.add(new BasicDBObject("by", "tutorials point"));
andList.add(new BasicDBObject("title", "MongoDB Overview"));
BasicDBObject and = new BasicDBObject("$and", andList);
BasicDBObject command = new BasicDBObject("find", "collectionName");
command.append("filter", and);
mongoTemplate.executeCommand(command);

Related

Correct use case of String parameter in SetQuery function of SolrQuery?

I have q
queryString = "select?wt=json&rows=0&indent=true&facet=true&q=*:*&facet=true&facet.field=outcome_type"
If queried like :
http://x.x.x.x:8983/solr/abc/queryString
it works. here abc is a core.
Now I would like to execute it programmatically, and using the following approach :
SolrQuery query = new SolrQuery();
query.setQuery(queryString);
QueryResponse resp = server.query(query);
here queryString as defined above, but it return the following error :
Exception in thread "main"
org.apache.solr.client.solrj.impl.HttpSolrServer$RemoteSolrException:
undefined field text
What I am missing here ? Or I need to build the query by set functions ?
I see few problems in your tentative.
You should not pass entire query string with the setQuery method. For almost each parameter available in query string there is a corresponding method in SolrQuery class.
SolrQuery does not support json format, SolrJ only supports the javabin and xml formats, I suggest to not specify any wt parameter.
So, you should use setQuery method only for q parameter:
query.setQuery("*:*");
For remaining parameters, the easiest way is use add method:
query.add("rows", "0"); // instead of setRows(0)
query.add("indent", "true");
query.add("facet", "true"); // ... setFacet(true)
query.add("facet.field", "outcome_type"); // ... addFacetField("outcome_type")
Hope this helps
I have used following approach to execute the query and it worked:
SolrQuery query = new SolrQuery();
query.setQuery(queryString);
query.setFacet(true);
query.set("wt", "json");
query.set("indent",true);
query.setRows(0);
query.addFacetField("outcome_type");
QueryResponse resp = server.query(query);

How do I execute a MongoDB js script using the Java MongoDriver

I have implemented a JavaScript function inside the Mongodb server using this example.
It works fine when I use mongo shell, but I want to run it from inside a Java program. This is the code:
public String runFunction() {
CommandResult commandResult1 = db.command("db.loadServerScripts()");
CommandResult commandResult2 = db.command("echoFunction(3)");
return commandResult2.toString();
}
I don't understand the result.
The previous answers does not work in MongoDB 3.4+. Th proper way to do this in version 3.4 and above is to create a BasicDBObject and use it as the parameter of Database.runCommand(). Here's an example.
final BasicDBObject command = new BasicDBObject();
command.put("eval", String.format("function() { %s return;}}, {entity_id : 1, value : 1, type : 1}).forEach(someFun); }", code));
Document result = database.runCommand(command);
Since MongoDB 4.2 the eval command is removed (it was deprecated in 3.0).
There is no more way to eval JavaScript scripts into MongoDB from the Java Driver.
See https://docs.mongodb.com/manual/reference/method/db.eval/
You should use DB.eval(), see the api docs and make sure that you don't do string concatenation. Pass the variables through instead.
I think your answer is probably the same answer as this other one on StackOverflow.
#Autowired
private MongoOperations mongoOperations;
private final BasicDBObject basicDBObject = new BasicDBObject();
#PostConstruct
private void initialize() {
basicDBObject.put("eval", "function() { return db.loadServerScripts(); }");
mongoOperations.executeCommand(basicDBObject);
}
private void execute() {
basicDBObject.put("eval", "function() { return echoFunction(3); }");
CommandResult result = mongoOperations.executeCommand(basicDBObject);
}
And then you can use something like:
ObjectMapper mapper = new ObjectMapper();
And MongoOperation's:
mongoOperations.getConverter().read(CLASS, DBOBJECT);
Just try to have some workaround depends on your requirements

MongoDB Java Driver - Use exists projection in find query

I want to get all documents where the field download does not exists
find{ "download" : {$exists: false}}
For Java I found an Example:
BasicDBObject neQuery = new BasicDBObject();
neQuery.put("number", new BasicDBObject("$ne", 4));
DBCursor cursor = collection.find(neQuery);
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
My Adaption is
BasicDBObject field = new BasicDBObject();
field.put("entities.media", 1);
field.put("download", new BasicDBObject("$exists",false));
System.out.println("Start Find");
DBCursor cursor = collection.find(query,field);
System.out.println("End Find Start Loop ALL 100k");
int i = 1;
while(cursor.hasNext())
The Exists Line is not working:
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: com.mongodb.MongoException: Unsupported projection option: $exists
at com.mongodb.MongoException.parse(MongoException.java:82)
at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:314)
at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:295)
at com.mongodb.DBCursor._check(DBCursor.java:368)
at com.mongodb.DBCursor._hasNext(DBCursor.java:459)
at com.mongodb.DBCursor.hasNext(DBCursor.java:484)
at ImgToDisk.main(ImgToDisk.java:61)
... 5 more
It have no clue right now which the right adaption would be, since I got my query working in the shell and with UMongo, the transfer to java seems to be not so easy to see.
you use
collection.find(query,field);
the DBObject that is the 2nd parameter to the find method is used to indicate which attributes of the resulting documents you want to be returned. It is useful for reducing network load.
In your example, you try to put an $exists clause into the field DBObject. That won't work.
The 2nd parameter object can only have attribute values of 1(include this attribute) or 0(exclude).
Put it into the first DBObject called query instead.
Also see here and here
you can use DBCollection to do that with JAVA API
public List<BasicDBObject> Query(String collection, Map<String, String> query, String... excludes) {
BasicDBObject bquery = new BasicDBObject(query);
BasicDBObject bexcludes = new BasicDBObject(excludes.length);
for (String ex : excludes) {
bexcludes.append(ex, false);
}
return db.getCollection(collection, BasicDBObject.class).find(bquery).projection(bexcludes)
.into(new ArrayList<BasicDBObject>());
}
db is MongoDataBase
We need to specify two things.
First :
collection.find(query,field);
The above command is not from MongoDB Java driver.
That means we can run only in the mongo shell (or in the mongo Compass) and not in the java.
Second:
to limit the fields in java you can use projection() like the following code
find(queryFilter)
.projection(fields(include("title", "year"),exclude("_id")))
Complete Example:
Bson queryFilter = eq("cast", "Salma Hayek");
//or Document queryFilter = new Document("cast", "Salma Hayek");
Document result =
collection
.find(queryFilter)
//.limit(1) if you want to limit the result
.projection(fields(include("title", "year"),exclude("_id")))
//or .projection(fields(include("title", "year"), excludeId()))
//or .projection(new Document("title", 1).append("year", 1))
.iterator()
.tryNext();

$push and $set in same MongoDB update

I'm trying to use MongoDB's Java driver to make two updates ($set and $push) to a record in the same operation. I'm using code similar to the following:
BasicDBObject pushUpdate = new BasicDBObject().append("$push", new BasicDBObject().append("values", dboVital));
BasicDBObject setUpdate = new BasicDBObject().append("$set", new BasicDBObject().append("endTime", time));
BasicDBList combinedUpdate = new BasicDBList();
combinedUpdate.add( pushUpdate);
combinedUpdate.add( setUpdate);
collection.update( new BasicDBObject().append("_id", pageId), combinedUpdate, true, false);
When I combine the $set and $push into the same update via a BasicDBList, I get an IllegalArgumentException: "fields stored in the db can't start with '$' (Bad Key: '$push')".
If I make two separate updates, both pushUpdate and setUpdate produce valid results.
Thanks!
I don't know Java driver, but do you have to create a list there? What happens if you try this code?
BasicDBObject update = new BasicDBObject().append("$push", new BasicDBObject().append("values", dboVital));
update = update.append("$set", new BasicDBObject().append("endTime", time));
collection.update( new BasicDBObject().append("_id", pageId), update, true, false);
This should produce the equivalent of
db.collection.update({_id: pageId}, {$push: {values: dboVital}, $set: {endTime: time}});
Whereas your code produces (I suspect) this:
db.collection.update({_id: pageId}, [{$push: {values: dboVital}}, {$set: {endTime: time}}]);
BasicDBObject update = new BasicDBObject().append("$push", new BasicDBObject().append("values", dboVital));
update = update.append("$set", new BasicDBObject().append("endTime", time));
collection.update( new BasicDBObject().append("_id", pageId), update, true, false);
My mongodb version is 3.4.20 and while using
db.collection.update({_id: pageId}, [{$push: {values: dboVital}}, {$set: {endTime: time}}]);
I received error
[thread1] Error: field names cannot start with $ [$push] :
To solve that error we can use:
db.collection.update({_id: pageId}, {$push: {values: dboVital}, $set: {endTime: time}});

How to query mongodb with “like” using the java api?

this question is very similar to another post
I basically want to use the mongodb version of the sql "like" '%m%' operator
but in my situation i'm using the java api for mongodb, while the other post is using mongodb shell
i tried what was posted in the other thread and it worked fine
db.users.find({"name": /m/})
but in java, i'm using the put method on the BasicDBObject and passing it into the find() method on a DBCollections object
BasicDBObject q = new BasicDBOBject();
q.put("name", "/"+m+"/");
dbc.find(q);
but this doesn't seem to be working.
anyone has any ideas?
You need to pass an instance of a Java RegEx (java.util.regex.Pattern):
BasicDBObject q = new BasicDBObject();
q.put("name", java.util.regex.Pattern.compile(m));
dbc.find(q);
This will be converted to a MongoDB regex when sent to the server, as well as any RegEx flags.
You must first quote your text and then use the compile to get a regex expression:
q.put("name", Pattern.compile(Pattern.quote(m)));
Without using java.util.Pattern.quote() some characters are not escaped.
e.g. using ? as the m parameter will throw an exception.
To make it case insensitive:
Document doc = new Document("name", Pattern.compile(keyword, Pattern.CASE_INSENSITIVE));
collection.find(doc);
In spring data mongodb, this can be done as:
Query query = new Query();
query.limit(10);
query.addCriteria(Criteria.where("tagName").regex(tagName));
mongoOperation.find(query, Tags.class);
Document doc = new Document("name", Pattern.compile(keyword));
collection.find(doc);
Might not be the actual answer, ( Executing the terminal query directly )
public void displayDetails() {
try {
// DB db = roleDao.returnDB();
MongoClient mongoClient = new MongoClient("localhost", 5000);
DB db = mongoClient.getDB("test");
db.eval("db.test.update({'id':{'$not':{'$in':[/su/]}}},{$set:{'test':'test3'}},true,true)", new Object[] {});
System.out.println("inserted ");
} catch (Exception e) {
System.out.println(e);
}
}
if(searchType.equals("employeeId"))
{
query.addCriteria(Criteria.where(searchType).regex(java.util.regex.Pattern.compile(searchValue)));
employees = mongoOperations.find(query, Employee.class, "OfficialInformation");
}

Categories

Resources