In this blog, we will explain nested queries and their use in Elasticsearch. These queries enable you to search for documents containing a ddmFieldArray of related information, simplifying the management of complex data. By utilizing nested queries, you can filter results based on specific conditions within the ddmFieldArray, ensuring that search results accurately reflect the connections between fields. This approach is particularly beneficial for structured data, such as news articles, where each article can have several tags or details. We can use nested queries effectively with journal articles, helping us find more accurate and relevant search results based on related information. This makes it easier to find content that matches specific needs.
We will demonstrate how to create a nested query in Elasticsearch to filter news articles based on a specific field in a ddmFieldArray. First, we will outline a basic structure for our news articles, including the title, description, and a flag indicating whether an article is the latest news. Next, we will guide you through the steps to construct an Elasticsearch query that identifies articles marked as the latest, and we’ll implement this query in Java. This example will enable you to easily locate news content based on specific criteria in nested fields.
Prerequisite:
- Basic knowledge of Liferay
- Liferay DXP/Portal 7.4+
- Elasticsearch Setup
- Kibana (optional)
- Basic Elasticsearch Query Knowledge
- Indexing Sample Data
How to Make Nested Query to Filter Searches by DDMFieldArray Element
Step 1: Creating the News Structure
We define a structure for our news articles, which includes fields for the title, description, and an indicator of whether it's the latest news.
News Title: The title of the news article.
Description: A brief description of the news content.
Latest News: A field indicating whether the news is the latest (YES/NO).
Step 2: Creating Web Content
In this step, we will create two examples of web content, one indicating that it is the latest news and the other as an archived item.
Step 3: Writing Elasticsearch Query
In this step, we’ll construct an Elasticsearch query to search for articles that are categorized as the latest news. Specifically, we will look for articles where the Latest News field is set to "YES"
Query Breakdown
1) Query Structure: The query utilizes the Elasticsearch GET method to search within the specified index (liferay-20096).
The main components of the query are:
- Bool Query: This allows us to combine multiple conditions.
- Nested Query: This is used because ddmFieldArray is a nested object, allowing us to search within it.
2)Query Components
- Must:This array contains conditions that must be satisfied for the documents to be included in the results.
- Nested Path: We specify the path to the nested field ddmFieldArray.
- Match Conditions:
1) The first condition matches the field name for Latest News.
2) The second condition checks if the value for Latest News is "YES".
Below is a query searches in ddmFieldArray for specific information. It looks for items where the field name is "ddm__keyword__34817__latestNews_en_US" and the value is "YES". You can change the search terms to look for any field in ddmFieldArray that you want, and you can also search for different fields using ddmFieldArray.ddmFieldName to find the data you need.
Kibana Response:
Step 4: Implementing Elasticsearch Query in Java
In this step, we will create a Java implementation to perform the Elasticsearch query for retrieving articles categorized as the latest news. We will use a BooleanQuery to structure our query logically.
- Below is a method called fetchWebContentDataUsingNestedQuery that gets web content based on specific criteria from a search system, likely Elasticsearch. It starts by creating an empty list to store the results and builds a query with two parts: one to find a specific field related to the structure ID and another to look for the latest news value. These parts are combined into a nested query that excludes certain results. The search is set up to allow empty searches and focuses on items of the JournalArticle type for the current company. After running the search, it processes the results and converts them into NewsDTO objects.
- The convertWebContentData method takes a list of search results and turns them into NewsDTO objects. It starts by looping through each search result, where it gets the associated document and extracts a key called entryClassPK. This key is used to find the latest JournalArticle. Then, it reads the article's content in XML format, focusing on the English version. The method retrieves the title and description from the XML and uses this information to create a new NewsDTO. Finally, it adds each filled NewsDTO to the response list, effectively preparing the search results for further use.
- The getNodeText method gets text from an XML node based on a given field reference. It takes two inputs: the root node of the XML and a string called fieldReference that points to the element you want. The method uses XPath to look for nodes that have a specific attribute, searching for dynamic-element nodes that contain dynamic-content. If it finds matching nodes, it returns the text from the first one; if not, it returns an empty string. This method is useful for extracting specific information from XML.
Conclusion:
In this blog, we explore how to create a nested query in Elasticsearch within the context of Liferay Development to filter results using elements from a ddmFieldArray. We begin by defining a simple structure for our news articles, including fields such as title, description, and a flag for the latest news. Examples are provided for both a current news article and an archived one. The main focus is on building a nested query that checks if the latest news field is set to "YES." Finally, we demonstrate how to implement this query in Java using a Boolean query, an essential technique in Liferay Development that enables us to efficiently locate specific articles based on criteria within nested fields.