Reindex selected _source fields using Rest high level client in java - java

I want to re_index only selected fields from my document in elasticsearch using Rest High level client.
I know the elasticsearch query to achieve that but I don't know it's equivalent query using rest client.
Following is the elasticsearch query which I am trying to implement using rest client -
{
"body" : {
"source" : {
"index" : "my source index name",
"_source" : "id, name, rollNo"
},
"dest" : {
"index" : "my destination index name"
}
}
}
To write its equivalent query using rest client in java, I have used the following code -
ReindexRequest reindexRequest = new ReindexRequest();
reindexRequest.setSourceIndices("source index name").setDestIndex("destination index name");
reindexRequest.setDocTypes("id", "name", "rollNo", "_doc");
client.reindex(reindexRequest,RequestOptions.DEFAULT);
But the above code is not working as expected. It's re_indexing all the fields of my document. I want only selective 3 fields to be re_indexed from each doc.

You need to use below code as setDocTypes is not used for source filtering.
As there is no direct method available for setting source filter so you need to change underlying search request suing below code.
ReindexRequest reindexRequest = new ReindexRequest();
reindexRequest.setSourceIndices("source index name").setDestIndex("destination index name");
reindexRequest.setDocTypes("_doc");
String[] include=new String[] {"id", "name", "rollNo"};
String[] exclude=new String[] {"test"};
reindexRequest.getSearchRequest().source().fetchSource(include, exclude);
client.reindex(reindexRequest,RequestOptions.DEFAULT);

Related

Query to search value in side array of object

I want to apply criteria inside object of array if it matches, but I am not able to find any documentation or example where I can find that using spring-data-cosmosdb library. I am using 2.3.0 version of library.
Example of Json
{
"id" : 1,
"address" : [
{
"street" : "abc"
...
},
{
"street" : "efg"
...
}
]
}
I wan to search all documents in which address is having street name equals "abc". Below is spring boot code that I am using to search in cosmosDb. But it is not returning expected results.
List<Criteria> criteriaList = new ArrayList<>();
criteriaList.add(Criteria.getInstance(CriteriaType.IN, "addresses.street", Collections.singletonList("abc")));
List<User> users = cosmosTemplate.find(new DocumentQuery(criteriaList.get(0), CriteriaType.AND)), User.class, COLLECTION_NAME);
I also tried with address[0].street, but it is throwing exception of operation not supported.
Strongly recommend upgrading to spring-data-cosmosdb v3 (at least version 3.22.0). The v2 connector has been legacy for some time. Using the latest connector, the below would accomplish your goal.
Criteria filterCriteria = Criteria.getInstance(CriteriaType.ARRAY_CONTAINS, "address",
Collections.singletonList(new ObjectMapper().readTree("{\"street\":\"abc\"}")),
Part.IgnoreCaseType.NEVER);
CosmosQuery cosmosQuery = new CosmosQuery(filterCriteria);
Iterable<User> results = cosmosTemplate.find(cosmosQuery, User.class, COLLECTION_NAME);
for (User user : results)
System.out.println("doc id: " + user.getId());

How to create a deep insert structure using Olingo Client?

How to POST the following JSON structure using Apache OLINGO client? What is the best way to build up this structure? Are there any examples?
{
"itemNumber": "ITEM1"
"lines": [
{
componentNumber": "COMPONENT1"
},
{
componentNumber": "COMPONENT2"
}
]
}
The following Java example using the Olingo Client works for me to post the following JSON structure:
{
"itemNumber": "ITEM1"
"lines": [
{
componentNumber": "COMPONENT1"
},
{
componentNumber": "COMPONENT2"
}
]
}
Java code using OLINGO CLient
public void deepInsertExample(){
//Initiate the ODATA client
ODataClient client = ODataClientFactory.getClient();
client.getConfiguration();
getClient().getObjectFactory();
//Initiate the Client Object Factory
ClientObjectFactory factory = getClient().getObjectFactory();
//Create Line Item 1
ClientEntity lineItem1 = factory.newEntity(new FullQualifiedName("ODATA.LineItem"));
lineItem1.getProperties()
.add(factory.newPrimitiveProperty("componentNumber", factory.newPrimitiveValueBuilder().buildString("COMPONENT2")));
//Create Line Item 2
ClientEntity lineItem2 = factory.newEntity(new FullQualifiedName("ODATA.LineItem"));
lineItem2.getProperties()
.add(factory.newPrimitiveProperty("componentNumber", factory.newPrimitiveValueBuilder().buildString("COMPONENT1")));
//Initiate the entity set
ClientEntitySet entitySet = factory.newEntitySet();
//Add Line Item 1 and Line Item 2 to the Enity
entitySet.getEntities().add(lineItem1);
entitySet.getEntities().add(lineItem2);
//Create the Lines LInk
ClientLink linesLink = factory.newDeepInsertEntitySet("Lines", entitySet);
ClientComplexValue complexValueCreate = factory.newComplexValue("Lines");
complexValueCreate.getNavigationLinks().add(linesLink);
//Create the Item object
ClientEntity item = factory.newEntity(new FullQualifiedName("ODATA.Item"));
item.getProperties()
.add(factory.newPrimitiveProperty("itemNumber", factory.newPrimitiveValueBuilder().buildString("ITEM1")));
//Add the Lines(Entity Set) link to Item Object
item.addLink(linesLink);
//Post the Item
URI absoluteUri = client.newURIBuilder("URL").build();
ODataEntityCreateRequest<ClientEntity> request = client.getCUDRequestFactory()
.getEntityCreateRequest(absoluteUri, item);
request.setAccept("application/json;odata.metadata=minimal");
request.execute();
}
You will have to specify the the NavigationPropertyName in the deep part. So for your sample payload it would look like
{
"itemNumber": "ITEM1",
"lines": {
"componentNumber":"COMPONENT1",
"componentNumber":"COMPONENT2",
}
}
You can refer to this post in SO to get details about n level nesting
The above answer asuumes that your NavigationProperty is named lines, you can substitute it with the right name by looking at service/$metadata
The answer assumes that you are trying to do deep inserts in a odata2 service, for OData4 the concept remains the same but syntax might vary a bit. Please refer to the payload descripted in documentation in case of OData 4

AWS textract Extract the meta-data and confidence score

Hi all i have extracted the document meta-data from AWS texttract Asynchronous call using java SDK but the meta-data is segregated into multiple blocks and it's huge.
How to extract the confidence score, value and its field name separately using java code i want to extract result something like below:
[{
"Field" : "FirstName",
"Value" : "XXXXX",
"confidence Score" : "98.88"
},
{
"Field" : "LastName",
"Value" : "XXXXX",
"confidence Score" : "65.98"
}]
Could anyone please suggest how to extract the field,value and its confidence score from aws texttract document meta-data?
anyone having any idea on this?
AWS has provided an example for mapping key and value pairs in python. You can use this code to understand the logic and come up with your own code in JAVA.
Source: https://docs.aws.amazon.com/textract/latest/dg/examples-extract-kvp.html
I have just begun with AWS Textract too in Java and wow what a great tool ! I have included code in my answer at this link if you would like to take a look :)
It extracts the keys and values. I suggest you create a model with Key, Value and confidence scores and then create an object for each key value pair
public static ArrayList<KVPair> getKVObjects(List<Block> keyMap, List<Block> valueMap, List<Block> blockMap ) {
ArrayList<KVPair> labelValues = new ArrayList<>();
Block value_block;
for (Block key_block : keyMap) {
value_block = findValueBlock(key_block, valueMap);
String key = getText(key_block, blockMap);
Float top = value_block.getGeometry().getBoundingBox().getTop();
Float left = value_block.getGeometry().getBoundingBox().getLeft();
Float confidenceScore = value_block.getConfidence();
Optional<KVPair> label= (labelValues.stream().filter(x-> x.getLabel().equals(key)).findFirst());
Property property = new Property();
property.setValue(getText(value_block, blockMap));
property.setLocationLeft(left);
property.setLocationTop(top);
property.setConfidenceScore(confidenceScore);
if(label.isPresent()){
label.get().setProperties(property);
}else{
KVPair KVPair = new KVPair();
KVPair.setLabel(key);
KVPair.setProperties(property);
labelValues.add(KVPair);
}
}
return labelValues;
}
AWS-Textract-Key-Value-Pair Java - thread "main" java.lang.NullPointerException

Full Text Search in CouchDB

I am developing an web application on GWT Framework (JAVA). I am using CouchDB(NoSQL Database)
for storing user profile, user question and answers. I am new in NoSQL Database so i need to implement full text search in my application.
Example : " What is Java ?"
Desired Result : It could be found all the question which have all three words What, is, Java .
So there is any idea how to achieve this result in couchdb.
Use couchdb lucene The integration with couchdb is straightforward and it would be perfect for your use case. Couch-db lucene supports the entire query syntanx of lucene. For your problem the + could be used.
The "+" or required operator requires that the term after the "+" symbol exist somewhere in a the field of a single document.
Here is a sample query
http://localhost:5984/_fti/local/database/_design/design_name/index_name?q=+"What is java"
You can implement it using CouchDB List Functions.
I have a document where I need to search for keywords in name and description field. So, I created a view which will emit doc id as key and doc.name,doc._id,doc.description as value.
Now I created a List function which will use Javascript match function and give me the matching list of doc ids.
Sample Query:
http://localhost:5984/dashboard/_design/testSearch/_list/results/ByName?searchQuery=What is Java
{
"_id": "_design/testSearch",
"lists": {
"results": "function(head, req) { var query= new RegExp(req.query.searchQuery,'i'); var arr=new Array(); var key; var row; while(row = getRow()) { if(row.value[0].match(query) || row.value[2].match(query)) { arr.push([row.value[0].toUpperCase(),row.value[1]]); key = row.key;}} arr.sort(); send('{\"'+key+'\":\"'+arr+'\"}');}"
},
"views": {
"ByName": {
"map": "function (doc) {\n if((doc.isdeleted==\"false\" || doc.isdeleted==false) && doc.userid && doc.name){\n emit(doc._id,[doc.name,doc._id,doc.description]);\n }\n}"
}
},
"language": "javascript"
}

MongoDB nested documents searching

How do I search through mongodb documents where documents have nested documents. For example I have a collection of private messages. Each private message has two nested documents - one representing the sending user and the other representing the receiving use. Both nested documents have the form -
userID: 34343,
name: Joe Bloggs
I would like to be able to search for all mail messages sent by a user (e.g. search the sender user nested document).
I am using the java driver. Do I need to create a DBObject which represents the nested document?
Thanks
As i understand u have document structure like this:
{
"someProperty" : 1,
"sendingUser" : {
userID : 34343,
name : "Joe Bloggs"
},
"recivingUser" : {
userID : 34345,
name : "Joe Bloggs"
}
}
So if you need find sending user with userID = 34345 you just need do following(i just think that is so, because actually i am working with c# driver for mongo):
DBCollection coll = db.getCollection("privateMessages")
query = new BasicDBObject();
query.put("sendingUser.userID", new BasicDBObject("$eq", 34345));
cur = coll.find(query); // all documents with sendingUser.userID = 34345 will be //returned by cursor
Also check tutorial for java driver
For MongoDB Java Driver v3.2.2. You can do something like this:
FindIterable<Document> iterable = collection.find(Document.parse("{\"sendingUser.userID\": \"34343\"}"));
FindIterable<Document> iterable = collection.find(Document.parse("{\"sendingUser.name\": \"Joe Bloggs\"}"));
You can put the $eq inside the JSON style query string. Like { <field>: { $eq: <value> } }.

Categories