Java - MongoDB Compund Index Text Search - java

I am using MongoDB latest version 2.12 Java Driver, in Eclipse. However, even after extensive searching on SO as well as Google, I could not resolve my problem.
Here is my code snippet:
mongoClient_m = new MongoClient();
db_m = mongoClient_m.getDB("atlascompare");
coll_m = db_m.getCollection("CollRMOB");
BasicDBObject doc = new BasicDBObject("ErrorName", "RMOB RULE_INFO")
.append("ErrorCause", "Database Out Of Sync")
.append("Resolution", "Try clearing your cache, or check database ver")
.append("TechnicalDat", new BasicDBObject("Java Null Pointer", 203).append("Java File Not Found Exception", 102));
coll_m.insert(doc);
doc = new BasicDBObject("ErrorName", "ERROR X_2609")
.append("ErrorCause", "CAUSE X_2609")
.append("Resolution", "PERFORM X_2609")
.append("TechnicalDat", new BasicDBObject("Java X_2609_1", 203).append("Java X_2609_2", 102));
coll_m.insert(doc);
doc = new BasicDBObject("ErrorName", "ERROR Y_2609")
.append("ErrorCause", "CAUSE Y_2609")
.append("Resolution", "PERFORM Y_2609")
.append("TechnicalDat", new BasicDBObject("Java Y_2609_1", 203).append("Java Y_2609_2", 102));
coll_m.insert(doc);
Here is the output I get on printing the docs:
{ "_id" : { "$oid" : "53e306577bdc3279309da4e3"} , "ErrorName" : "RMOB RULE_INFO" , "ErrorCause" : "Database Out Of Sync" , "Resolution" : "Try clearing your cache, or check database ver" , "TechnicalDat" : { "Java Null Pointer" : 203 , "Java File Not Found Exception" : 102}}
{ "_id" : { "$oid" : "53e306577bdc3279309da4e4"} , "ErrorName" : "ERROR X_2609" , "ErrorCause" : "CAUSE X_2609" , "Resolution" : "PERFORM X_2609" , "TechnicalDat" : { "Java X_2609_1" : 203 , "Java X_2609_2" : 102}}
{ "_id" : { "$oid" : "53e306577bdc3279309da4e5"} , "ErrorName" : "ERROR Y_2609" , "ErrorCause" : "CAUSE Y_2609" , "Resolution" : "PERFORM Y_2609" , "TechnicalDat" : { "Java Y_2609_1" : 203 , "Java Y_2609_2" : 102}}
However a simple text search does not show any output!!
BasicDBObject textSearch = new BasicDBObject("$text", "ERROR X_2609");
BasicDBObject search = new BasicDBObject("$search", textSearch);
System.out.println(coll_m.find(search));
Prints the following lines:
Cursor id=0, ns=atlascompare.CollRMOB, query={ "$search" : { "$text" : "ERROR X_2609"}}, numIterated=0, readPreference=primary
Can anybody please guide me what I am doing wrong?!
Edit 1: Also, I made sure the indexes were made. Here is the output when I print the indexes:
Indexes present ----------------------------
{ "v" : 1 , "key" : { "_id" : 1} , "name" : "_id_" , "ns" : "atlascompare.CollRMOB"}
{ "v" : 1 , "key" : { "_fts" : "text" , "_ftsx" : 1} , "name" : "$**_text" , "ns" : "atlascompare.CollRMOB" , "weights" : { "$**" : 1} , "default_language" : "english" , "language_override" : "language" , "textIndexVersion" : 2}

It looks to me that your query is not correct.
The query should look like: (in the MongoDB Shell)
db.CollRMOB.find( { $text : { $search : "ERROR X_2609" } } );
So in your Java code it should be something like:
BasicDBObject textSearch = new BasicDBObject("$search", "ERROR X_2609");
BasicDBObject search = new BasicDBObject("$text", textSearch);
// the print the documents
System.out.println(coll_m.find(search).toArray() );
Tug

Related

Mongo Java - list all documents which has data as phone number or credit card number or zip code when field name is not known to us

Could you please suggest a option in Mongo Java to find all documents which has data as phone number or credit card number or zip code, when field name is not known to us.
I tried this but this is not working at all.
AggregateIterable<Document> output = collection.aggregate(
Arrays.asList(
new Document(
"$project", new Document(
"x", new Document(
"$objectToArray", "$$CURRENT"
)
)
),
new Document("$unwind", "$x"),
new Document(
"$match", new Document(
"x.k", new Document(
"$in", new BasicDBObject("$regex", "^(ISBN(-10)?:? )?([-0-9xX ]{13}|[0-9X]{10})$")
)
)
)
)
);
For example Input
{
"_id" : ObjectId("5a0bf2604510c319181df436"),
"name" : "Oneindb2",
"number" : 11,
"phonenumber" : 111111
}
{
"_id" : ObjectId("5a0bf2604510c319181df437"),
"dname" : "creditCardtwoindb2",
"zipc" : "5670228"
}
{
"_id" : ObjectId("5a0bf2604510c319181df439"),
"name" : "creditCardfourindb2",
"CHECKnumber" : 56,
"checkISO" : "second_iso"
}
{
"_id" : ObjectId("5a0bf2604510c319181df43a"),
"name" : "creditCardfiveindb2",
"ddnumber" : 56,
"ISOS" : "second_iso"
}
{
"_id" : ObjectId("5a0bf2604510c319181df438"),
"cname" : " 57656yuio89789"
"personnumber" : 33,
"NISO" : "three_iso"
}
*Expected output is*
{
"_id" : ObjectId("5a0bf2604510c319181df436"),
"name" : "Oneindb2",
"number" : 11,
"pnumber" : 111111
}
{
"_id" : ObjectId("5a0bf2604510c319181df437"),
"dname" : "creditCardtwoindb2",
"zipc" : "5670228"
}
{
"_id" : ObjectId("5a0bf2604510c319181df438"),
"cname" : " 57656yuio89789"
"number" : NumberInt(33),
"ISO11" : "three_iso"
}
because these documents fields (at least one field) has either phone number or credit card number or zip code
Note: field names are not same in all the documents it may vary.

Multiple update in mongodb using java

I've this document:
{
"_id" : ObjectId("54140782b6d2ca6018585093"),
"user_id" : ObjectId("53f4ae1ae750619418a20467"),
"date" : ISODate("2014-09-13T08:59:46.709Z"),
"type" : 0,
"tot" : 2,
"additional_info" : {
"item_id" : ObjectId("540986159ef9ebafd3dcb5d0"),
"shop_id" : ObjectId("53f4cc5a6e09f788a103d0a4"),
"ap_id" : ObjectId("53f4cc5a6e09f788a103d0a5")
},
"transactions" : [
{
"_id" : ObjectId("54140782b6d2ca6018585091"),
"date_creation" : ISODate("2014-09-13T08:59:46.711Z"),
"type" : -1
},
{
"_id" : ObjectId("54140782b6d2ca6018585092"),
"date_creation" : ISODate("2014-09-13T08:59:46.788Z"),
"type" : 1
}
]
}
and I need to add 2 more field to the first transaction opbject:
- date_execution: date
- result: this bson document
{ "server_used" : "xxx.xxx.xxx.xxx:27017" , "ok" : 1 , "n" : 1 , "updated_executed" : true} (m_OR.getDocument() in the following code example)
to obtaing that document
{
"_id" : ObjectId("54140811b6d25137753c1a1a"),
"user_id" : ObjectId("53f4ae1ae750619418a20467"),
"date" : ISODate("2014-09-13T09:02:09.098Z"),
"type" : 0,
"tot" : 2,
"additional_info" : {
"item_id" : ObjectId("540986159ef9ebafd3dcb5d0"),
"shop_id" : ObjectId("53f4cc5a6e09f788a103d0a4"),
"ap_id" : ObjectId("53f4cc5a6e09f788a103d0a5")
},
"transactions" : [
{
"_id" : ObjectId("54140811b6d25137753c1a18"),
"date_creation" : ISODate("2014-09-13T09:02:09.100Z"),
"type" : -1,
"result" : {
"server_used" : "xxx.xxx.xxx.xxx:27017",
"ok" : 1,
"n" : 1,
"updated_executed" : true
},
"date_execution" : ISODate("2014-09-13T09:02:15.370Z")
},
{
"_id" : ObjectId("54140811b6d25137753c1a19"),
"date_creation" : ISODate("2014-09-13T09:02:09.179Z"),
"type" : 1
}
]
}
The only way I was able to do that is the do 2 separates updates (update is a my wrapper funciont that execute the real updates in mongodb and it works fine):
// where
BasicDBObject query = new BasicDBObject();
query.append("transactions._id", m_Task.ID());
// new value for result - 1st upd
BasicDBObject value = new BasicDBObject();
value.put("$set",new BasicDBObject("transactions.$.date_execution",new Date()));
update(this._systemDB, "activities", query, value);
// new value for date_execution - 2nd upd
value = new BasicDBObject();
value.put("$set",new BasicDBObject("transactions.$.result",m_OR.getDocument()));
update(this._systemDB, "activities", query, value);
If I try to do this:
BasicDBObject value = new BasicDBObject();
value.put("$set",new BasicDBObject("transactions.$.date_execution",new Date()));
value.put("$set",new BasicDBObject("transactions.$.result",m_OR.getDocument()));
or = update(this._systemDB, "activities", query, value);
just the 2nd set will be applied.
Is there any way do avoid the double execution and apply the update with just one call?
Basic rule of "hash/map" objects is that you can only have one key. It's the "highlander" rule ( "There can be only one" ) applied in general reason. So just apply differently:
BasicDBObject value = new BasicDBObject();
value.put("$set",
new BasicDBObject("transactions.$.date_execution",new Date())
.add( new BasicDBObject("transactions.$.result",m_OR.getDocument() )
);
So basically "both" field arguments are part of the "$set" statement as in the serialized form:
{
"$set": {
"transactions.$.date_execution": new Date(),
"transactions.$.result": m_Or.getDocument()
}
}
Which is basically what you want in the end.
Your suggestion was right, just had to fix a little the syntax this way:
BasicDBObject value = new BasicDBObject();
value.put("$set",
new BasicDBObject("transactions.$.date_execution",new Date())
.append("transactions.$.result",m_OR.getDocument())
);
This worked perfectly ;)
Thanks!
Samuel

$set and positional operator doesn't work in Java?

I have the following document in MongoDb collection called hosts
{ "_id" : ObjectId("532aeec040a83df82181ff3c"),
"os" : "WINDOWS",
"name" : "Host 1",
"bas" : [
{ "wwn" : "EE:00:11:FF", "id" : "1" },
{ "wwn" : "AA:00:11:BB", "id" : "2" } ]
}
Now I want to update ba of id=1 in Host of name=Host 1 to { "wwn" : "AA:BB:CC:DD", "id" : "11" }. After the update the result will be
{ "_id" : ObjectId("532aeec040a83df82181ff3c"),
"os" : "WINDOWS",
"name" : "Host 1",
"bas" : [
{ "wwn" : "AA:BB:CC:DD", "id" : "11" },
{ "wwn" : "AA:00:11:BB", "id" : "2" } ]
}
For this I used the mongo shell command
db.hosts.update( { name : "Host 1", "bas.id" : "1" },
{ "$set" : { "bas.$" : { wwn : "AA:BB:CC:DD", id : "11"} }} );
which worked great. Now I wanted to do the same using Java drivers and here is my code
BasicDBObject example = new BasicDBObject("name", "Host 1").append("bas\uff0eid", "1");
BasicDBObject newValue = new BasicDBObject("\u0024set", new BasicDBObject("bas\uff0e\u0024", new BasicDBObject().append("wwn", "AA:BB:CC:DD).append("id","11")) ;
collection.update(example, newValue);
In the above code I had to replace . with \uff0 and $ with \u0024 to avoid exception being thrown. This update call is not updating the collection. When I inspected the BasicDBObject.toString() the JSON were same as what I had typed on console. Please help me.
I don't understand why you should need to write $ and . as Unicode escapes. I tried running your code with the actual characters in them and it worked fine with the 2.11 Java driver.
But your code has two problems: 1) the full stop . is \u002e, not \uff0e, which is a very different character. 2) the syntax of the last part of the statement is not correct, but that is probably a copying error.
Here's the code that I used, and it worked fine (I only created the objects and didn't actually run it against the database but I don't see why that wouldn't work).
BasicDBObject example = new BasicDBObject("name", "Host 1").append("bas.id", "1");
BasicDBObject newValue = new BasicDBObject("$set",
new BasicDBObject("bas.$",
new BasicDBObject()
.append("wwn", "AA:BB:CC:DD").append("id","11"))) ;
https://github.com/mongodb/mongo-java-driver/blob/master/src/main/com/mongodb/DBCollectionImpl.java#L249
If your value object doesn't have a key starting with $ then it will check the embedded document for illegal characters. Can you post your original code that had this problem, without the escapes?

remove _id from mongodb result java

My code is
DBCollection collection = db.getCollection("volume");
DBCursor cursor = collection.find();
DBObject resultElement = cursor.next();
Map resultElementMap = resultElement.toMap();
System.out.println(resultElementMap);
And the result is:
{_id=521b509d20954a0aff8d9b02, title={ "text" : "Volume Of Work
Orders" , "x" : -20.0}, xAxis={ "title" : { "text" : "2012 "} ,
"categories" : [ "Jan" , "Feb" , "Mar" , "Apr" , "May" , "Jun" , "Jul"
, "Aug" , "Sep" , "Oct" , "Nov" , "Dec"]}, yAxis={ "min" : 1000.0 ,
"max" : 7000.0 , "title" : { "text" : "Volume(K)"} , "plotLines" : [ {
"label" : { "text" : "Average" , "x" : 25.0} , "color" : "black" ,
"width" : 2.0 , "value" : 30.0 , "dashStyle" : "solid"}]}, legend={
"backgroundColor" : "#FFFFFF" , "reversed" : true}, series=[ { "name"
: "Volume" , "showInLegend" : false , "data" : [ 2909.0 , 3080.0 ,
4851.0 , 3087.0 , 2960.0 , 2911.0 , 1900.0 , 3066.0 , 3029.0 , 5207.0 , 3056.0 , 3057.0]}]}
I need to remove _id from the result. I understand i need to play around with collection.find(), but please can anyone help me? Am not able to get sesired result
Two options:
You can remove the "_id" field from the map created:
...
resultElementMap.remove("_id");
System.out.println(resultElementMap);
Or you can ask the query results to not include the _id field:
DBObject allQuery = new BasicDBObject();
DBObject removeIdProjection = new basicDBObject("_id", 0);
DBCollection collection = db.getCollection("volume");
DBCursor cursor = collection.find(allQuery, removeIdProjection);
DBObject resultElement = cursor.next();
Map resultElementMap = resultElement.toMap();
System.out.println(resultElementMap);
See the documentation on projections for all of the details.
Another option to consider, if you are reading the results iteratively, is doing something like this:
final FindIterable<Document> foundResults = collection.find();
for (final Document doc : foundResults) {
doc.remove("_id");
// doc.toJson() no longer has _id
}

Update data with mongoDB in Java

I have a little bug with my script:
BasicDBObject change = new BasicDBObject();
BasicDBObject account =
new BasicDBObject().append("$set", new BasicDBObject().append("status", 0));
account.append("pos.X", getX());
account.append("pos.Y", getY());
account.append("pos.Z", getZ());
change.append("pseudo", gPlayer);
coll.update(change, account);
And the structure of mongoDB is :
{
pseudo: "pseudo"
email: "email"
password: "password"
status: "1"
pos: [
{X: "90.45}
{Y: "90.45}
{Z: "90.45}
]
}
But this is not working! No value is modified.
Thanks for your help.
Java is a very verbose language, and sometimes it is easiest to first write your query using the JS shell, make sure it performs as desired, and then translate it into Java.
By adding System.out.println(account.toString()) to your Java code, I can see that your Update document looks like the following, which is not valid:
{ "$set" : { "status" : 0} , "pos.X" : "90.45" , "pos.Y" : "90.45" , "pos.Z" : "90.45"}
From your question, it is not entirely clear what you would like your updated document to look like, but I am guessing that you would like to modify the values of "status" and "pos.0.X", "pos.1.Y", and "pos.2.Z". Because X, Y, and Z are all stored as individual embedded documents inside an array, they will have to be referenced by their positions in order to be updated at the same time. If possible, you might find it preferable to rearrange your document structure such that X, Y, and Z are all stored inside the same document, like so:
"pos" : {
"X" : "0",
"Y" : "0",
"Z" : "0"
}
This way, you will be able to access each variable more easily using dot notation, pos.X, pos.Y, pos.Z, which from your post looks like what you were intending. More information on embedded documents may be found in the "Dot Notation (Reaching into Objects)" documentation:
http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29
Here is an Update statement that will modify the above values:
> db.pseudo.find({ "pseudo" : "gPlayer"}).pretty()
{
"_id" : ObjectId("4f904ebb5bebd4375b759c90"),
"email" : "email",
"password" : "password",
"pos" : [
{
"X" : "90.45"
},
{
"Y" : "90.45"
},
{
"Z" : "90.45"
}
],
"pseudo" : "gPlayer",
"status" : "1"
}
> db.pseudo.update({"pseudo" : "gPlayer"}, { "$set" : { "status" : 0 , "pos.0.X" : "0" , "pos.1.Y" : "0" , "pos.2.Z" : "0"}})
> db.pseudo.find({ "pseudo" : "gPlayer"}).pretty()
{
"_id" : ObjectId("4f904ebb5bebd4375b759c90"),
"email" : "email",
"password" : "password",
"pos" : [
{
"X" : "0"
},
{
"Y" : "0"
},
{
"Z" : "0"
}
],
"pseudo" : "gPlayer",
"status" : 0
}
>
Translated into Java this is:
BasicDBObject change = new BasicDBObject("pseudo", "gPlayer");
BasicDBObject setDoc = new BasicDBObject();
setDoc.append("status", "0");
setDoc.append("pos.0.X", "0");
setDoc.append("pos.1.Y", "0");
setDoc.append("pos.2.Z", "0");
BasicDBObject account = new BasicDBObject("$set", setDoc);
coll.update(change, account);
I realize that I guessed a little bit about exactly the update that you would like to do, but hopefully the above will get you pointed in the right direction!

Categories

Resources