IN order to test couchbase, I am needing to create servlet that edit in 1.000 JSON documents row '"flag": false' to '"flag":true'. How i can do this?
My view, that finds documents with row '"flag": false':
function (doc, meta) {
if (meta.type == "json" && doc.flag == false) {
emit(doc.flag, null);
}
}
My servlet, that print results:
doGet(....
View view = client.getView("des1", "flag");
Query query = new Query();
query.setIncludeDocs(true);
ViewResponse result = client.query(view, query);
for(ViewRow row : result) {
resp.getWriter().println(row.getId());
}
Sorry for my bad English)
You cannot edit the fields in the JSON document directly. What you must do is to retrieve the documents you want to update (you already get them from the view), convert them to a Java object, edit the "flag" property, serialize the Java object back to JSON and replace the document with the new one.
You can use GSON to take care of the conversion between a java object and json.
Related
SearchRequest searchRequest = Requests.searchRequest(indexName);
SearchSourceBuilder builder = new SearchSourceBuilder();
Gson gson = new Gson();
QueryBuilder querybuilder = QueryBuilders.wrapperQuery(query);
query : {
"range": {
"timecolumn": {
"gte":"2022-10-07T09:45:13Z",
"lte":"2022-10-07T09:50:50Z"
}
}
}
While passing the above Query I am getting Parser Exception , I cannot change the date format as data in DB is getting inserted in same format .
Need Advice on :
How can we parse this kind of timestamp in ElasticSearch Java , if not
How can we control pattern updation during data insertion like my column in defined as text which takes date format "2022-10-07T09:45:13Z" as text .
either I have to pass this format in ES Parser or I have to change format to 2022-10-07 09:45:13 during insertion itself .
I cannot convert for each row after inserting because we have lakhs of data
As you are mentioning, Elasticsearch storing timecolumn as text type hence i will suggest to change mapping of timecolumn to date type and you will be able to use range query with date. Because if you store date as text and applied range then it will not return a expected result.
{
"mappings": {
"properties": {
"timecolumn": {
"type": "date"
}
}
}
}
Now coming to your Java code issue, You can use below code for creating range query in Java as you are using Java client.
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
QueryBuilder query = QueryBuilders.rangeQuery("timecolumn").gte("2022-10-07T09:45:13Z").lte("2022-10-07T09:50:50Z");
searchSourceBuilder.query(query);
searchRequest.source(searchSourceBuilder);
Regarding your concern about reindexing data:
I cannot convert for each row after inserting because we have lakhs of
data
You can use Reindex API to move data from original index to temp index and delete your original index. Then, defined the index with proper mapping and again use same Reindex API to copy data from temp index to original index with new mapping.
I have created a MongoDB Collection using the following code, I want to update this collection add a new column named "username" and also want to change the data type of roleId from String to Long. Please advice how to do this in Java Mongo API
fun createUsers(mongoDB: MongoDatabase) {
var collOptions: ValidationOptions = ValidationOptions()
collOptions.validator(
Filters.and(
Filters.exists("userId"),
Filters.type("userId",BsonType.STRING),
Filters.exists("roleId"),
Filters.type("roleId", BsonType.INT32)
)
)
collOptions.validationLevel(ValidationLevel.STRICT)
collOptions.validationAction(ValidationAction.ERROR)
mongoDB.createCollection("user", CreateCollectionOptions().validationOptions(collOptions))
}
I have to Update the Xml document object generated using Apache XMLbeans.There are two ways I am trying to update and save the document.
Step 1 : I am parsing the document and updating with the new values and saving with the parsed document itself.
private boolean updateContact(ContactType contacts, String contactFilePath, String name) throws Exception {
ContactsDocument contactDoc = ContactsDocument.Factory.parse(new File(contactFilePath));
ContactType contact = contactDoc.getContactType();
contact.setName(name);
contactDoc.save(new File(contactFilePath) , XmlUtils.getDefaultFileSavingOptions());
}
Step 2 : I am passing the updated document type and creating new instance of the xml document and saving with the updated type.
private boolean writeContact(ContactType contactType, String contactFilePath) throws Exception {
ContactsDocument contactsDoc = ContactsDocument.Factory.newInstance();
contactsDoc.setContactType(contactType);
contactsDoc.save(new File(contactFilePath), XmlUtils.getDefaultFileSavingOptions());
}
The step 2 is working but i want to know, will step 1 work ? and which is the efficient way of doing it for this scenario.
The Step 1 works perfect with the XML default file saving options and it does not modifies or removes any of the existing namespaces present in the file.
private boolean updateContact(ContactType contacts, String contactFilePath, String name) throws Exception {
ContactsDocument contactDoc = ContactsDocument.Factory.parse(new File(contactFilePath));
ContactType contact = contactDoc.getContactType();
contact.setName(name);
contactDoc.save(new File(contactFilePath) , XmlUtils.getDefaultFileSavingOptions());
}
It is also good approach to parse the file and save the changes on top of it, Instead of parse and instantiating the xml document for every updates.
I'm trying to get the objectId of an object that I have updated - this is my java code using the java driver:
Query query = new Query();
query.addCriteria(Criteria.where("color").is("pink"));
Update update = new Update();
update.set("name", name);
WriteResult writeResult = mongoTemplate.updateFirst(query, update, Colors.class);
Log.e("object id", writeResult.getUpsertedId().toString());
The log message returns null. I'm using a mongo server 3.0 on mongolab as I'm on the free tier so it shouldn't return null. My mongo shell is also:
MongoDB shell version: 3.0.7
Is there an easy way to return the object ID for the doc that I have just updated? What is the point of the method getUpsertedId() if I cannot return the upsertedId?
To do what I want, I currently have to issue two queries which is highly cumbersome:
//1st query - updating the object first
Query query = new Query();
query.addCriteria(Criteria.where("color").is("pink"));
Update update = new Update();
update.set("name", name);
WriteResult writeResult = mongoTemplate.updateFirst(query, update, Colors.class);
//2nd query - find the object so that I can get its objectid
Query queryColor = new Query();
queryColor.addCriteria(Criteria.where("color").is("pink"));
queryColor.addCriteria(Criteria.where("name").is(name));
Color color = mongoTemplate.findOne(queryColor, Color.class);
Log.e("ColorId", color.getId());
As per David's answer, I even tried his suggestion to rather use upsert on the template, so I changed the code to the below and it still does not work:
Query query = new Query();
query.addCriteria(Criteria.where("color").is("pink"));
Update update = new Update();
update.set("name", name);
WriteResult writeResult = mongoTemplate.upsert(query, update, Colors.class);
Log.e("object id", writeResult.getUpsertedId().toString());
Simon, I think its possible to achieve in one query. What you need is a different method called findAndModify().
In java driver for mongoDB, it has a method called findOneAndUpdate(filter, update, options).
This method returns the document that was updated. Depending on the options you specified for the method, this will either be the document as it was before the update or as it is after the update. If no documents matched the query filter, then null will be returned. Its not required to pass options, in that case it will return the document that was updated before update operation was applied.
A quick look at the mongoTemplate java driver docs here: http://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/FindAndModifyOptions.html tells me that you can use the method call:
public <T> T findAndModify(Query query,
Update update,
FindAndModifyOptions options,
Class<T> entityClass)
You can also change the FindAndModifyOptions class to take on an 'upsert' if the item was not found in the query.If it is found, the object will just be modified.
Upsert only applies if both
The update options had upsert on
A new document was actually created.
Your query neither has upsert enabled, nor creates a new document. Therefore it makes perfect sense that the getUpsertedId() returns null here.
Unfortunately it is not possible to get what you want in a single call with the current API; you need to split it into two calls. This is further indicated by the Mongo shell API for WriteResults:
The _id of the document inserted by an upsert. Returned only if an
upsert results in an insert.
This is an example to do this with findOneAndUpdate(filter,update,options) in Scala:
val findOneAndUpdateOptions = new FindOneAndUpdateOptions
findOneAndUpdateOptions.returnDocument(ReturnDocument.AFTER)
val filter = Document.parse("{\"idContrato\":\"12345\"}")
val update = Document.parse("{ $set: {\"descripcion\": \"New Description\" } }")
val response = collection.findOneAndUpdate(filter,update,findOneAndUpdateOptions)
println(response)
I have a form that runs a java agent on the WebQueryOpen event. This agent pulls data from a DB2 database and then puts them into the computed text fields I have placed on the form and are displayed whenever I open the form in the browser. This is working for me. However, when I try to use RichTextFields I get a ClassCastException error. No document is actually saved, I just open the form in the browser using this domino URL - https://company.com/database.nsf/sampleform?OpenForm
Sample code of simple text field - Displayed with w/o problems
Document sampledoc = agentContext.getDocumentContext();
String samplestr = "sample data from db2";
sampledoc.replaceItemValue("sampletextfield", samplestr);
When I tried using rich text field
Document sampledoc = agentContext.getDocumentContext();
String samplestr = "sample data from db2";
RichTextItem rtsample = (RichTextItem)sampledoc.getFirstItem('samplerichtextfield');
rtsample.appendText(samplestr); // ClassCastException error
Basically, I wanted to use rich text field so that it could accommodate more characters in case I pull a very long string data.
Screenshot of the field (As you can see it's a RichText)
The problem is that you're trying to access a regular Item as a RichTextItem.
The RichTextItem are special fields that are created with its own method just like this:
RichTextItem rtsample = (RichTextItem)sampledoc.createRichTextItem('samplerichtextfield');
It's different to the regular Items that can be created with a simple sampledoc.replaceItemValue(etc).
So, if you want to know if a item is RichTextItem and if it does not exist, create it, you can do this:
RichTextItem rti = null;
Item item = doc.getFirstItem("somefield");
if (item != null) {
if (item instanceof RichTextItem) {
//Yay!
rti = (RichTextItem) item;
} else {
//:-(
}
} else {
rti = doc.createRichTextItem("somefield");
//etc.
}