Edit SearchSourceBuilder in Elasticsearch Java API - elasticsearch

I am given an existing SearchSourceBuilder that needs to have a boolean clauses added to it.
How do I add the clause without changing the existing query using the Elasticsearch API?
public void example(SearchSourceBuilder searchSourceBuilder) {
SearchQuery originalQuery = searchSourceBuilder.query();
//Edit the originalQuery to include a boolean must_not
SearchSourceBuilder.query(originalQuery);
}

Related

Elasticsearch simultaneously search by two documents

I have two different documents in the Elasticsearch - Decision and Nomination.
Right now I can only search all of the documents wit Decision type.
I use Spring Data Elasticsearch for this purpose:
PageRequest pageRequest = DecisionUtils.createPageRequest(pageNumber, pageSize);
MultiMatchQueryBuilder fuzzyMmQueryBuilder = multiMatchQuery(query, "name", "description").fuzziness("AUTO");
BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder().should(fuzzyMmQueryBuilder);
NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
nativeSearchQueryBuilder.withIndices(ESDecision.INDEX_NAME).withTypes(ESDecision.TYPE).withPageable(pageRequest);
NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.withQuery(boolQueryBuilder).withPageable(pageRequest).build();
return elasticsearchTemplate.queryForPage(nativeSearchQuery, ESDecision.class);
Is it possible to update this code to search by Decision and Nomination simultaneously in order to get the search result from both of them ? If the answer is yes - please show an example how to implement this and also please show how to determine at search results who is Decision and who is Nomination ? Is there any classification field that can be added into search result entity for this purpose ?

How to create a search with or clause using Elasticsearch

I want to create a query with Elasticsearch Java API but I don't know how to create an OR clause? What I want to query is;
SELECT *
FROM USERS
WHERE (user.name = "admin") AND (user.message LIKE "test*") AND (user.age = "30" OR user.status = "major")
I have created a query like below but I don't know how to create an OR clause like sql query;
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("name", "admin"));
boolQueryBuilder.must(QueryBuilders.matchQuery("message", "test*"));
boolQueryBuilder.must(QueryBuilders.matchQuery("age", "30"));
boolQueryBuilder.must(QueryBuilders.matchQuery("status","major"));
You simply need to capture the OR condition inside another bool/should query
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.matchQuery("name", "admin"));
boolQueryBuilder.mustNot(QueryBuilders.matchQuery("message", "test*"));
BoolQueryBuilder orQuery = QueryBuilders.boolQuery();
orQuery.should(QueryBuilders.matchQuery("age", "30"));
orQuery.should(QueryBuilders.matchQuery("status","major"));
orQuery.minimumNumberShouldMatch(1);
boolQueryBuilder.must(orQuery);
PS: not sure why you have a mustNot for your second constraint.
The "should" keyword in bool queries works like "OR", but in Elasticsearch those queries are not very sharp as everything is scored.
Have a look at:
https://www.elastic.co/guide/en/elasticsearch/guide/current/bool-query.html#bool-query
Also there are very good examples in the book Elasticsearch in Action.

Elasticsearch - get source field data with java api

I'm using elastic search with jest (as java client).
I need some fields that is in nested document and since cannot get nested fields as pair, I need '_source' to get them.
Here is previous question to get them in ES query[ Link ], and It works well.
BUT cannot convert its query as jest code.
Below is my try.
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(
query
)
.fields( // need _source but no method.
"oid",
"_source.events.activityoid",
"_source.events.worktime");
Try using fetchSource() like this:
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
.query(query)
.fetchSource(new String[] {
"oid",
"events.activityoid",
"events.worktime"
}, null);

Filtering with DoubleMetaphoneFilter in Lucene

I want to use DoubleMetaphone in Lucene programmatically.
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-phonetic</artifactId>
<version>4.4.0</version>
</dependency>
The above package contains appropriate classes.
This filter can be used in Solr via setting xml.
But I want it to use in Java programmaticaly.
analyzer = new StandardAnalyzer(Version.LUCENE_44);
String field = "title";
Query q = new QueryParser(Version.LUCENE_44, field, analyzer).parse(querystr);
int hitsPerPage = 100;
IndexReader reader = DirectoryReader.open(index);
IndexSearcher searcher = new IndexSearcher(reader);
TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);
searcher.search(q, collector);
ScoreDoc[] hits = collector.topDocs().scoreDocs;
But I don't know how I use the filter.
To use this filter, you'll need to create your own custom Analyzer, similar to the example in the Analyzer documentation. If you want to add a metaphone filter to
Analyzer analyzer = new Analyzer() {
#Override
protected TokenStreamComponents createComponents(String fieldName, Reader reader) {
final StandardTokenizer source = new StandardTokenizer(Version.LUCENE_44, reader);
source.setMaxTokenLength(StandardAnalyzer.DEFAULT_MAX_TOKEN_LENGTH);
TokenStream filter = new StandardFilter(Version.LUCENE_44, filter);
filter = new LowerCaseFilter(Version.LUCENE_44, filter);
filter = new StopFilter(Version.LUCENE_44, filter, StopAnalyzer.ENGLISH_STOP_WORDS_SET);
filter = new DoubleMetaphoneFilter(filter, 4, true);
return new TokenStreamComponents(source, filter)
}
}
That is just an example, of course. Setup you Analyzer however makes sense for the data you want to index.
Also, keep in mind that this filter will need to be applied at index time, as well as query time, so you will need to reindex your data with this filter applied to index the metaphone codes.

How to update multiple fields using java api elasticsearch script

I am trying to update multiple value in index using Java Api through Elastic Search Script. But not able to update fields.
Sample code :-
1:
UpdateResponse response = request.setScript("ctx._source").setScriptParams(scriptParams).execute().actionGet();
2:
UpdateResponse response = request.setScript("ctx._source.").setScriptParams(scriptParams).execute().actionGet();
if I mentioned .(dot) in ("ctx._source.") getting illegalArgument Exception and if i do not use dot, not getting any exception but values not getting updated in Index.
Can any one tell me the solutions to resolve this.
First of all, your script (ctx._source) doesn't do anything, as one of the commenters already pointed out. If you want to update, say, field "a", then you would need a script like:
ctx._source.a = "foobar"
This would assign the string "foobar" to field "a". You can do more than simple assignment, though. Check out the docs for more details and examples:
http://www.elasticsearch.org/guide/reference/api/update/
Updating multiple fields with one script is also possible. You can use semicolons to separate different MVEL instructions. E.g.:
ctx._source.a = "foo"; ctx._source.b = "bar"
In Elastic search have an Update Java API. Look at the following code
client.prepareUpdate("index","typw","1153")
.addScriptParam("assignee", assign)
.addScriptParam("newobject", responsearray)
.setScript("ctx._source.assignee=assignee;ctx._source.responsearray=newobject ").execute().actionGet();
Here, assign variable contains object value and response array variable contains list of data.
You can do the same using spring java client using the following code. I am also listing the dependencies used in the code.
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder;
private UpdateQuery updateExistingDocument(String Id) {
// Add updatedDateTime, CreatedDateTime, CreateBy, UpdatedBy field in existing documents in Elastic Search Engine
UpdateRequest updateRequest = new UpdateRequest().doc("UpdatedDateTime", new Date(), "CreatedDateTime", new Date(), "CreatedBy", "admin", "UpdatedBy", "admin");
// Create updateQuery
UpdateQuery updateQuery = new UpdateQueryBuilder().withId(Id).withClass(ElasticSearchDocument.class).build();
updateQuery.setUpdateRequest(updateRequest);
// Execute update
elasticsearchTemplate.update(updateQuery);
}
XContentType contentType =
org.elasticsearch.client.Requests.INDEX_CONTENT_TYPE;
public XContentBuilder getBuilder(User assign){
try {
XContentBuilder builder = XContentFactory.contentBuilder(contentType);
builder.startObject();
Map<String,?> assignMap=objectMap.convertValue(assign, Map.class);
builder.field("assignee",assignMap);
return builder;
} catch (IOException e) {
log.error("custom field index",e);
}
IndexRequest indexRequest = new IndexRequest();
indexRequest.source(getBuilder(assign));
UpdateQuery updateQuery = new UpdateQueryBuilder()
.withType(<IndexType>)
.withIndexName(<IndexName>)
.withId(String.valueOf(id))
.withClass(<IndexClass>)
.withIndexRequest(indexRequest)
.build();

Resources