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");
}
Related
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);
Can someone please provide a complete tailable cursor example in Java? I am using the 3.0 driver and all examples appear to be 2.x. I have only mongo-java-driver-3.0.0.jar in my classpath. I want to get all documents as they are inserted in my capped collection.
//this does not work...
MongoCollection<BasicDBObject> col = database.getCollection(colName, BasicDBObject.class);
DBCursor cur = col.find().sort(new BasicDBObject("$natural", 1))
.addOption(Bytes.QUERYOPTION_TAILABLE)
.addOption(Bytes.QUERYOPTION_AWAITDATA);
// And this does not work...
BasicDBObjectBuilder builder = BasicDBObjectBuilder.start();
builder.add("messageType","STATUS_REQUEST");
DBObject searchQuery = builder.get();
DBObject sortBy = BasicDBObjectBuilder.start("$natural", 1).get();
BasicDBObjectBuilder builderForFields = BasicDBObjectBuilder.start();
DBObject fields = builderForFields.get();
DBCursor cursor = new DBCursor(col, searchQuery, fields, ReadPreference.primary() );
cursor.sort(sortBy);
cursor.addOption(Bytes.QUERYOPTION_AWAITDATA);
cursor.addOption(Bytes.QUERYOPTION_TAILABLE);
//this does work but only returns the messageNumber field. I need the doc.
MongoCursor<Long> c = database.getCollection(colName).distinct("messageNumber", Long.class).iterator();
I see that the MongoCursor interface was added in 3.0. What is that for and does it replace DBCursor?
Thanks a lot
A bit late to the party, but in case you still need help:
find(query).projection(fields).cursorType(CursorType.TailableAwait).iterator();
That code applies to the MongoCollection class.
CursorType is an enum and it has the following values:
Tailable
TailableAwait
Corresponding to the old DBCursor addOption Bytes types:
Bytes.QUERYOPTION_TAILABLE
Bytes.QUERYOPTION_AWAITDATA
I hope that helps.
This is what you might be looking for - EVENT Streaming in MongoDB 3.0.* using new api i.e. 3.0.2
Document query = new Document(); \\here use { indexedField: { $gt: <lastvalue> } index is not used(except for auto deleting documents) but created in capped collection
Document projection = new Document();
MongoCursor<Document> cursor= mongocollection.find(query).projection(projection).cursorType(CursorType.TailableAwait).iterator(); //add .noCursorTimeout(true) here to avoid timeout if you are working on big data
while (cursor.hasNext()){
Document doc = cursor.next();
//do what you want with doc
}
This way mongo cursor will check for new entries in capped collection
In your last line, replace .distinct("messageNumber", Long.class) with .find().
distinct(String fieldName, Class<TResult> resultClass) returns only the unique values of the one field you request.
find() returns all documents of the collection with all of their fields.
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
I am using MongoDB with Java Driver (http://tinyurl.com/dyjxz8k). In my application I want it to be possible to give results that contains a substring of the users search-term. The method looks like this:
*searchlabel = the name of a field
*searchTerm = the users searchword
private void dbSearch(String searchlabel, String searchTerm){
if(searchTerm != null && (searchTerm.length() > 0)){
DBCollection coll = db.getCollection("MediaCollection");
BasicDBObject query = new BasicDBObject(searchlabel, searchTerm);
DBCursor cursor = coll.find();
cursor = coll.find(query);
try {
while(cursor.hasNext()) {
System.out.println(cursor.next());
//view.showResult(cursor.next());
}
} finally {
cursor.close();
}
}
}
Does anybody have any idea about how I can solve this? Thanks in advance =) And a small additional question: How can I handle the DBObjects according to presentation in (a JLabel in) view?
For text-searching in Mongo, there are two options:
$regex operator - however unless you have a simple prefix regexp, queries won't use an index, and will result in a full scan, which usually is slow
In Mongo 2.4, a new text index has been introduced. A text query will split your query into words, and do an or-search for documents including any of the words. Text indexes also eliminate some stop-words and have simple stemming for some languages (see the docs).
If you are looking for a more advanced full-text search engine, with more powerful tokenising, stemming, autocomplete etc., maybe a better fit would be e.g. ElasticSearch.
I use this method in the mongo console to search with a regular expression in JavaScript:
// My name to search for
var searchWord = "alex";
// Construct a query with a simple /^alex$/i regex
var query = {};
query.animalName = new RegExp("^"+searchWord+"$","i");
// Perform find operation
var lionsNamedAlex = db.lions.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();