Search in Liferay - elasticsearch

I have created one structure which is followed by web content. Structure Contains 2 fields. One is Area name and the second is Zip Code. I stored data in web content followed by this structure.
I want to search for data based on zip code or area name entered by the user. I want to provide a dropdown to the user to select criteria to search like by Zipcode / by Area name.
The problem is web content data is stored in XML format. So whenever a user searches for a keyword it will return all results which contain given text. I want to restrict that.
I am using this method for search data.
List<JournalArticle> results = JournalArticleLocalServiceUtil.search(
themeDisplay.getCompanyId(), //company id
themeDisplay.getScopeGroupId(), // group id
null, //folderIds Log list
0, //classname
null, //version
null,//title
null, //description
searchkeyword, // here put your keywords to search
new Date(), // startDate
new Date(), // endDate
0, //status
null, //review Date
QueryUtil.ALL_POS,
QueryUtil.ALL_POS, null);

You have to search using Liferay search API directly to Elasticsearch, filtering by DDM fields.
Each field of webcontent structures are translated to a DDM Field in Elasticsearch side.
You have information about how to query JournalArticle filtering by DDM fields in following links:
Liferay documentation: https://portal.liferay.dev/docs/7-2/frameworks/-/knowledge_base/f/search-queries-and-filters
Stackoverflow 1: http://stackoverflow.com/questions/24523689/liferay-6-2-custom-fulltext-search-portlet-implementation#24564208
Stackoverflow 2: http://stackoverflow.com/questions/30982986/get-distinct-values-for-a-group-of-fields-from-a-list-of-records
Liferay forums 1: https://community.liferay.com/forums/-/message_boards/message/108179215
Liferay forums 2: https://community.liferay.com/forums/-/message_boards/message/86997787
Liferay forums 3: https://community.liferay.com/forums/-/message_boards/message/84031533
(note: some links are related to 6.2 version, but 7.x queries should be very similar)
In Liferay Portal 7.x, the names of DDM fields that you have to query are built in DDMIndexerImpl.encodeName(...) method, see:
https://github.com/liferay/liferay-portal-ee/blob/cba537c39989bbd17606e4de4aa6b9ab9e81b30c/modules/apps/dynamic-data-mapping/dynamic-data-mapping-service/src/main/java/com/liferay/dynamic/data/mapping/internal/util/DDMIndexerImpl.java#L243-L268
DDM fields names follows following pattern:
Fields that are configured as keyword: ddm__keyword__{structrureId}__{fieldname}_{locale}
Other fields: ddm__{structrureId}__{fieldname}_{locale}
Note: in order to get structureId, you should query DDMStructure filtering by structureKey, if you hardcode the structureId, you can have problems in case you export/import the structure because structureId is recalculated during import process.

Related

How to modify data table column values in Kibana

In Elastic search we store events, I have built data table which aggregates based on event types. I have filter which checks for event.keyword : "job-completed". I am getting the count as 1 or 0 but i want to display as completed / in-progress.
How to achieve this in Kibana ?
The best and more effective way to do this is to add another field with and to complete it at the ingest time.
It the best solution regarding on performance. But it can lead to an heavy work.
You can also use a scripted field to do this without touching your data.
Do to stack management > kibana > index pattern and select your index.
Select scripted field tab and fill in form.
Name : your_field
language: painless
type: string
format: string
script:
if(doc['event.keyword'].value=='job-completed'){
return "completed";
}else {
return "in progress";
}
I got to few information on your real data to be able to give you a working code, so you'll have to modify it to fit your needs.
Then refresh you visualization and you can use your new field

Index ID identification in Elasticsearch/Kibana visualization

"kibanaSavedObjectMeta": {
"searchSourceJSON": "{\"index\":\"4eb9f840-3969-11e8-ae19-552e148747c3\",\"filter\":[],\"query\":{\"language\":\"lucene\",\"query\":\"\"}}"
}
The above mentioned snippet is a exported JSON of a Kibana visualization. Without exporting this json is there a direct way to get this
\"index\":\"4eb9f840-3969-11e8-ae19-552e148747c3\ index id.
And if i am not wrong this is supposed to be the index id as its common across visualization with same index.
So, you can retrieve all index patterns using this query
GET .kibana/_search?q=type:index-pattern&size=100
Additionally, you can retrieve a specific set of index pattern given its name using
GET .kibana/_search?q=type:index-pattern%20AND%20index-pattern.title:indexname
Similarly, regarding visualizations, you can retrieve one by name using
GET .kibana/_search?q=type:visualization%20AND%20visualization.title:vizname

Fast query to retrieve those records that has published date

How do I query using Sitecore fast query to retrieve those records that has published date? I tried using the below but it did not return any value.
And how do I retrieve only the last node? Because when I use descendant::*, it will also return the parent out.
fast:/sitecore/content/test//[##parentid='{5656C582-A876-41E6-8441-A3F0BA0D2601}'
and #Publish>'20170101T000000']/descendant::
The Sitecore Field name for the publish field is not Publish. You need to make use of the following syntax for publish field: #__Publish.
You can see the right field name in the Inheritance from the template. You will be able to see the field names as shown below:
So, your query will looks as follows:
fast:/sitecore/content/Home//*[##parentid='{5656C582-A876-41E6-8441-A3F0BA0D2601}' and #__Publish > '20170101T000000']/*

Elasticsearch with multiple search criteria

I am try to build a full text search engine using elasticsearch. We have a application which has conferences running across the globe. We have the future and past conferences data. For a POC we have already loaded the conferences details into elasticsearch and it contains fields like title,date,venue,geo_location of the venue as document.
I am able to do simple search using match all query. And also by using function_score I can get the current on going conferences and also using user geo location i can get nearby conferences to users location.
But there are some uses cases where i got stuck and could not proceed. Use cases are.
1) If user try to search with "title + location" then I should not use the user current geo location rather whatever user has provided the city_name use that place geo location and retrieve those doc. Here I know some programming is also required.
2) User search with "title + year", for ex. cardio 2014. User interested to see all the caridology conf of 2014 and it should retrieve that year documents only. But using function score it is retrieving the current years documents.
First of all let me know that above two use cases can be handled in single query. I am thinking to handle it one request, but got stuck.
A proper solution would require you to write your own query parser in your application (outside of elasticsearch) that will parse the query and extract dates, locations, etc. Once all features are extracted, the parser should generate a bool query where each feature would become an appropriate must clause. So, the date would became a range query, the location - geo_location query and everything else would go into a match query for full text matching. Then this query can be sent to elasticsearch.

Elasticsearch Jest update a whole document

I have an elasticsearch server which i'm accessing via a java server using the Jest client and i was looking for the best way to update multiple fields of a document each time.
I have looked to the documentation so far, and i have found that there are two way for doing it :
Partial update via a script : i don't think it is suitable for multiple field update (because i don't know the modified fields).
Whole document update: via re-indexing the whole document.
My question is how could i update the whole document knowing that Jest provide only update via a script?
Is it the best way to delete a document and indexing the updated version?
Already answered this in the github issue you also opened but again:
You should use the second way you linked (Whole document update) and there is no special API for it, it's just a regular index request. So you can do it simply by sending your Index request against the id of the document you want to update.
For example assuming you have below document already indexed in Elasticsearch within index people, type food, id 9:
{"user": "kramer", "fav_food": "jello"}
Then you would do:
String source = "{\"user\": \"kramer\", \"fav_food\": \"pizza\"}";
JestResult result = client.execute(
new Index.Builder(source)
.index("people")
.type("food")
.id(9)
.build()
);

Resources