How to use FunctionScoreQueryBuilder in ES 6 java api? - java

I want to upgrade from ES 1.7 to 6.0. I made all necessary changes and now I have a problem with FunctionScoreQueryBuilder.
I create a BoolQueryBuilder filter and works fine. Now I want to add score to my results but results are same with those I have without add ScoreFunction
ScoreFunctionBuilder fb = ScoreFunctionBuilders.scriptFunction("_score * (doc['field'].value!=0? 50000:1) ")
FunctionScoreQueryBuilder fsb = new FunctionScoreQueryBuilder(filter,fb)
SearchRequestBuilder srbPaged = client.prepareSearch(indexName)
.setFetchSource(includes, excludes)
.setQuery(fsb)

The code you posted just change the value of field[score],
you should sort results by score.
Just like
srbPaged.sort("_score", SortOrder.DESC)

Related

Are there any restrictions on Amazon neptune when using gremlin syntax?

I am using a graph database for my project, Neptune by AWS. Neptune uses gremlin syntax for graph queries. I was trying to execute a scenario where I have to filter the outgoing edges from a vertex on the basis of property on the edge. Let's call that property 'x'. The value of this property 'x' is of the form 'abc::xyz::ref'. This is to store multiple values on the edge, as Neptune does not allow multi values on edges. I have to do a contains check with three combinations and an exact match :-
'abc::'
'::abc'
'::abc::'
Exact match with 'abc'
I was trying to use filter command in the gremlin in my java code. The below code works fine with TinkerGraph in-memory, but when I connect it with Neptune and run the same query it throws some parsing exception.
String valueToCheck = "abc";
List<String> listOfValuesToCheck = new ArrayList<>();
listOfValuesToCheck.add("::abc");
listOfValuesToCheck.add("abc::");
listOfValuesToCheck.add("::abc::");
GraphTraversal<Vertex, Map<Object, Object>> gt24 = g.V().outE().has("x").filter(it -> {
String value = String.valueOf(it.get().value("x"));
if(value.equals(valueToCheck)){
return true;
}else {
for(String s: listOfValuesToCheck){
if(value.contains(s){
return true;
}
}
}
}).valueMap().with(WithOptions.tokens);
while (gt24.hasNext()) {
System.out.println(gt24.next());
}
Does someone know, why this is happening with Neptune? And is there a better way to do it that works with Neptune.
I have seen one more instance where Neptune did not throw an error but also gave back no results but the same work with TinkerGraph.
y - property on Edge
z - property on Vertex
GraphTraversal<Vertex, Map<String, Object>> gt13 = g.V(1, 2).project("id", "summary").by(T.id)
.by(__.outE().has("y", "e").inV().group().by("z"));
Neptune doesn't support lambdas steps.
you should try to replace your lambda code with other gremlin steps.
g.V().outE().has("x").or(
__.has('prop', 'abc'),
__.has('prop', TextP.containing('abc::')),
__.has('prop', TextP.containing('::abc')),
).valueMap().with(WithOptions.tokens)
example: https://gremlify.com/sjrd9lrwfr
It looks like you are trying to include in line code in your query. Amazon Neptune does not support that. However, Gremlin includes text predicates such as TextP.containing which you can use instead. The small number of Neptune differences are documented at https://docs.aws.amazon.com/neptune/latest/userguide/access-graph-gremlin-differences.html

Getting the size of arraylist from a MongoDB table

I am trying to get the count of followers from user table which is basically a array list using java programming.
I am using below query to get the count using command line interface.
db.userinfo.aggregate([{ $project : {followersCount : {$size: "$followers"}}}])
But I am not able to create the same query in java as I am new. Below is the code I wrote in java and I am getting com.mongodb.MongoCommandException: Command failed with error 17124: 'The argument to $size must be an array, but was of type: int' Error.
AggregateIterable<Document> elements = collectionUserInfo.aggregate(
Arrays.asList(new BasicDBObject("$project", new BasicDBObject("followers",
new BasicDBObject("$size", new BasicDBObject("followers",1).put("followers",new BasicDBObject("$ifNull", "[]")))))));
Can Anyone please help me with this
You can try something like with Java 8 and Mongo Driver 3.x version. You should try not to use old type ( BasicDbObject) and where possible use api method.
List<Integer> followersCount = collectionUserInfo.aggregate(
Arrays.asList(Aggregates.project(Projections.computed(
"followersCount",
Projections.computed("$size", "$followers"))
)
))
.map(follower -> follower.getInteger("followersCount"))
.into(new ArrayList<>());
I tried this and it worked fine.
AggregateIterable<Document> elements = collectionUserInfo.aggregate(
Arrays.asList(new BasicDBObject("$project", new BasicDBObject("followers",
new BasicDBObject("$size", "$followers")))));
Thanks

List array output and IBM's Watson Java SDK

I'm currently working on a translator using IBM's Watson and their Java SDK imported using Maven, and I'm currently having a hard time trying to figure out how to output the translated text into a text box. The translation results come back to me as:
[{
"translation": "Hello, World !"
}]
I think I'm not calling something correctly in my code:
LanguageTranslation service = new LanguageTranslation();
service.setUsernameAndPassword("<username>", "<password>");
TranslationResult translationResult = service.translate(txt_input.getText(), "en", "fr");
txt_translation.setText(translationResult.getTranslations().toString());
I think I'm not calling something correctly in my code. According to the documentation, the translated text returns as a list of translations, but I'm not sure how to make it output only the translation of what I enter in. Any suggestions?
EDIT: I'm still working out trying to fix the issue. I've tried:
java.util.List<Translation> translationText = translationResult.getTranslations();
txt_translation.setText(translationText.toString());
With and without the toString() added in. Still comes up as what it did before.
translationResult.getTranslations() returns the List<Translation>, so it is a list of Translation that you should iterate. For instance, in order to get the first translation, you should use:
translationResult.getTranslations().get(0)
, which returns Translation, and then use getTranslation() in order to get translated text.
For instance, translation for the first language should be reachable by:
translationResult.getTranslations().get(0).getTranslation()
Notice that for your specific example, just saying that you want from "en" to "fr" won't work. You have to select an existing translation model first, like this
LanguageTranslation service = new LanguageTranslation();
service.setUsernameAndPassword("xxx", "xxx");
//System.out.println(service.getModels()); // <<< get your model from here
//TranslationResult translationResult = service.translate("Hello World!", "en", "fr"); //<< does not work OOTB
TranslationResult translationResult = service.translate("Hello World!", "en-fr-conversational");
System.out.println(translationResult.getTranslations().get(0).getTranslation());
so you'll have
Bonjour monde !

Elasticsearch Update indexdocument

I need to update an index document for an elasticsearch table and this is the code I have implemented. But it is not working, what's wrong and how should I implement this?
My code.
Map<String, Object> matching_result;
for (SearchHit hit : response_text.getHits()) {
matching_result = hit.getSource();
String flag_value = matching_result.get("flag").toString();
matching_result.put("flag", true);
}
String indexString = JSONConverter.toJsonString(matching_result);
IndexResponse response = client.prepareIndex("index_name", "data").setSource(indexString).execute().actionGet();
boolean created = response.isCreated();
System.out.println("created or updated--------------------->" + created);
System.out.println("flag value==========" + matching_result.get("flag"));
return actual_theme;
(JSONConverter.toJsonString) is our library class for converting to json string.
What is wrong with this query?
Instead of updating the existing document it is creating a new one. I want to change the existing one.
Based on your example code, it looks like by "update" you mean you are trying to replace the entire document. In order to do this, you must specify the id of the document you wish to update.
Using the Java API, in addition to calling setSource on the IndexRequestBuilder, you would also need to supply the id by calling setId. For example:
IndexResponse response = client.prepareIndex("index_name", "data")
.setSource(indexString)
.setId(123) <----- supply the ID of the document you want to replace
.execute()
.actionGet();
Otherwise, just so you know, in ES you have the option to do a partial update. That is, only update certain fields in the document. This can be done with a script or by providing a partial document. Have a look at the documentation for the Update API.
In either case, you need to provide ES with the ID for the document you wish to modify.

Updating a document in Solr with Java

As everybody knows, the documentation of Solrj in the wiki is pretty poor. I managed to query the index using the CommonsHttpSolrServer, but never with the Embedded version. Anyway, now I'm using the EdgeNGrams to display auto-suggestions, and I have a field "count" in my index, so that I can sort the results by the number of times people queried the element.
What I want to do now, is to be able to update this "count" field in my Java program, which should be quite easy I guess? I looked at the test files from the source code, but it's very complicated, and trying to do something similar always failed for me. Maybe by using Solrj?
Thanks for your help.
Edit:
In my java code, I have:
CoreContainer.Initializer initializer = new CoreContainer.Initializer();
CoreContainer coreContainer = initializer.initialize();
What I expect to get at this point, is the cores defines in solr.xml present in the coreContainer, but there is no core there (but defaultCoreName says collection1). My solr.xml file is the same as in the example dir:
<solr persistent="false">
<cores adminPath="/admin/cores" defaultCoreName="collection1">
<core name="collection1" instanceDir="." />
</cores>
</solr>
Modified from this test example. To add a value to Solr and then subsequently modify it you can do the following:
//add value to Solr
doc = new SolrInputDocument();
doc.addField("id", "A");
doc.addField("value", 10);
client.add(doc);
client.commit();
//query Solr
SolrQuery q = new SolrQuery("id:A");
QueryResponse r = client.query(q);
//update value
SolrDocument oldDoc = r.getResults().get(0);
SolrInputDocument newDoc = new SolrInputDocument();
newDoc.addField("id", oldDoc.getFieldValue("id");
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("inc", 15);
newDoc.addField("value", map);
client.add(newDoc);
client.commit();
This increments the original 10 value to 25. You can also "add" to an existing field or simply "set" an existing value by changing what command you put what you put the in the HashMap.
I finally just store this count in Solr, then retrieve it and update it, then run an update, since it is not possible to update a single field in Solr and also the count field, which could be very handy!

Categories

Resources