PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label full-text-search. Show all posts
Showing posts with label full-text-search. Show all posts

Monday, October 24, 2022

[FIXED] How do I use PutMappingRequest with the Elasticsearch 8 Java API Client?

 October 24, 2022     date-range, elasticsearch, full-text-search, java     No comments   

Issue

I am able to find an object with a datetime range corresponding to 2022-07-27 when sending the following HTTP requests from Postman to an Elasticsearch 8.3.2 server.

PUT http://localhost:9200/commit
{
    "mappings": {
        "properties": {
            "dateTimeRange": {
                "type": "date_range",
                "format": "uuuu-MM-dd[['T'][ ]HH:mm[:ss[.[SSS][SS][S]][,[SSS][SS][S]]]][XXXXX][XXXX][X]"
            }
        }
    }
}

PUT http://localhost:9200/commit/_doc/commit20220727?refresh
{
    "dateTimeRange": {
        "gte": "2022-07-27T00:00:00.000Z", 
        "lte": "2022-07-27T23:59:59.999Z"
    }
}

PUT http://localhost:9200/commit/_doc/commit20220728?refresh
{
    "dateTimeRange": {
        "gte": "2022-07-28T00:00:00.000Z", 
        "lte": "2022-07-28T23:59:59.999Z"
    }
}

POST http://localhost:9200/commit/_search
{
    "query" : {
        "range" : {
            "dateTimeRange" : { 
                "gte": "2022-07-27T12:12:12.999Z",
                "lte": "9999-12-31T23:59:59.999Z"
            }
        }
    }
}

That being said, I am unable to use the Elasticsearch Java API Client and the query datetime:[2022-07-27T12\\:12\\:12.121Z TO *] to find an object with a date range corresponding to 2022-07-27.

In ElasticsearchIndexerAndQuerierTest.java, the code on line 158 under comment Attempt to search for commits with specific dateTime ranges yields the assertion error expected:<2> but was:<0>.

How do I resolve this assertion error?


ElasticsearchIndexerAndQuerierTest.java

package Com.TSL.ElasticsearchIndexerAndQuerier;

import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.util.List;

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.junit.Test;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.mapping.SourceField;
import co.elastic.clients.elasticsearch.core.DeleteRequest;
import co.elastic.clients.elasticsearch.core.DeleteResponse;
import co.elastic.clients.elasticsearch.core.IndexRequest;
import co.elastic.clients.elasticsearch.core.IndexResponse;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import co.elastic.clients.elasticsearch.indices.DeleteIndexRequest;
import co.elastic.clients.elasticsearch.indices.DeleteIndexResponse;
import co.elastic.clients.elasticsearch.indices.PutMappingRequest;
import co.elastic.clients.elasticsearch.indices.PutMappingResponse;
import co.elastic.clients.elasticsearch.indices.RefreshResponse;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;

public class ElasticsearchIndexerAndQuerierTest {

@Test
public void testElasticsearchIndexerAndQuerier() throws IOException {

    // Create a credentials provider.
    final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("elastic", "password"));
    
    // Create a REST client.
    RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost("localhost", 9200));
    HttpClientConfigCallback httpClientConfigCallback = new HttpClientConfigCallback() {
        @Override
        public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
            return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
        }
    };
    restClientBuilder.setHttpClientConfigCallback(httpClientConfigCallback);
    RestClient restClient = restClientBuilder.build();

    ElasticsearchTransport elasticsearchTransport = new RestClientTransport(restClient, new JacksonJsonpMapper());

    ElasticsearchClient client = new ElasticsearchClient(elasticsearchTransport);
    
    try {
    
        // Create index commit.
        CreateIndexRequest.Builder createIndexRequestBuilder = new CreateIndexRequest.Builder();
        createIndexRequestBuilder.index("commit");
        CreateIndexRequest createIndexRequest = createIndexRequestBuilder.build();
        CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest);
        System.out.println(createIndexResponse);
        
        // Store and index commit-dateTime strings as dates and commit-dangeTimeRange strings as date ranges.
        SourceField.Builder sourceFieldBuilder = new SourceField.Builder();
        String mappings =
            "{\n" +
            "    \"mappings\": {\n" +
            "        \"properties\": {\n" +
            "            \"id\": {\n" +
            "                \"type\": \"text\"\n" +
            "            },\n" +
            "            \"name\": {\n" +
            "                \"type\": \"text\"\n" +
            "            },\n" +
            "            \"dateTimeRange\": {\n" +
            "                \"type\": \"date_range\"\n" +
            "                \"format\": \"uuuu-MM-dd[['T'][ ]HH:mm[:ss[.[SSS][SS][S]][,[SSS][SS][S]]]][XXXXX][XXXX][X]\"\n" +
            "            }\n" +
            "        }\n" +
            "    }\n" +
            "}";
        sourceFieldBuilder.includes(mappings);
        SourceField sourceField = sourceFieldBuilder.build();
        PutMappingRequest.Builder putMappingRequestBuilder = new PutMappingRequest.Builder();
        putMappingRequestBuilder.index("commit");
        putMappingRequestBuilder.source(sourceField);
        PutMappingRequest putMappingRequest = putMappingRequestBuilder.build();
        PutMappingResponse putMappingResponse = client.indices().putMapping(putMappingRequest);
        System.out.println(putMappingResponse);
        
        // Index a commit.
        IndexRequest.Builder<Commit> indexRequestBuilder = new IndexRequest.Builder<>();
        indexRequestBuilder.index("commit");
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode dateTimeRange = objectMapper.readValue("{\"gte\":\"2022-07-27T00:00:00.000Z\",\"lte\":\"2022-07-27T23:59:59.999Z\"}", JsonNode.class);
        Commit commit = new Commit("commit20220727", "Commit 2022-07-27", dateTimeRange);
        indexRequestBuilder.id(commit.getId());
        indexRequestBuilder.document(commit);
        IndexResponse indexResponse = client.index(indexRequestBuilder.build());
        System.out.println(indexResponse);
        
        // Index a commit.
        indexRequestBuilder = new IndexRequest.Builder<>();
        indexRequestBuilder.index("commit");
        dateTimeRange = objectMapper.readValue("{\"gte\":\"2022-07-28T00:00:00.000Z\",\"lte\":\"2022-07-28T23:59:59.999Z\"}", JsonNode.class);
        commit = new Commit("commit20220728", "Commit 2022-07-28", dateTimeRange);
        indexRequestBuilder.id(commit.getId());
        indexRequestBuilder.document(commit);
        indexResponse = client.index(indexRequestBuilder.build());
        System.out.println(indexResponse);
        
        // Make sure searching can provide the commits.
        RefreshResponse refreshResponse = client.indices().refresh();
        System.out.println(refreshResponse);
        
        // Attempt to search for commits with specific dateTime ranges.        
        SearchRequest.Builder searchRequestBuilder = new SearchRequest.Builder();
        searchRequestBuilder.q("dateTimeRange:[2022-07-27T12:12:12.121Z TO *]");
        SearchRequest searchRequest = searchRequestBuilder.build();
        SearchResponse<Commit> searchResponse = client.search(searchRequest, Commit.class);
        System.out.println(searchResponse);
        List<Hit<Commit>> hits = searchResponse.hits().hits();
        System.out.println("Hits");
        System.out.println("-----");
        for (Hit<Commit> hit : hits) {
            System.out.println(hit.source());
        }
        System.out.println("-----");
        assertEquals(2, hits.size());

    } finally {
        
        // Delete the first commit.
        DeleteRequest.Builder deleteRequestBuilder = new DeleteRequest.Builder();
        deleteRequestBuilder.index("commit");
        deleteRequestBuilder.id("commit20220727");
        DeleteRequest deleteRequest = deleteRequestBuilder.build();
        DeleteResponse deleteResponse = client.delete(deleteRequest);
        System.out.println(deleteResponse);
        
        // Delete the second commit.
        deleteRequestBuilder = new DeleteRequest.Builder();
        deleteRequestBuilder.index("commit");
        deleteRequestBuilder.id("commit20220728");
        deleteRequest = deleteRequestBuilder.build();
        deleteResponse = client.delete(deleteRequest);
        System.out.println(deleteResponse);
        
        // Delete index commit.
        DeleteIndexRequest.Builder deleteIndexRequestBuilder = new DeleteIndexRequest.Builder();
        deleteIndexRequestBuilder.index("commit");
        DeleteIndexRequest deleteIndexRequest = deleteIndexRequestBuilder.build();
        DeleteIndexResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest);
        System.out.println(deleteIndexResponse);
    }
}
}

Solution

PutMappingRequest.source sets the _source property of the mappings, which is not what I wanted. My goal was to set the entire mappings from JSON, which can be done using PutMappingRequest.withJson.

The section of code from SourceField.Builder... to System.out.println(putMappingResponse); should be replaced with the following.

        PutMappingRequest.Builder putMappingRequestBuilder = new PutMappingRequest.Builder();
        putMappingRequestBuilder.index("commit");
        String mappings =
            "{\n" +
            "    \"properties\": {\n" +
            "        \"id\": {\n" +
            "            \"type\": \"text\"\n" +
            "        },\n" +
            "        \"name\": {\n" +
            "            \"type\": \"text\"\n" +
            "        },\n" +
            "        \"dateTimeRange\": {\n" +
            "            \"type\": \"date_range\",\n" +
            "            \"format\": \"uuuu-MM-dd[['T'][ ]HH:mm[:ss[.[SSS][SS][S]][,[SSS][SS][S]]]][XXXXX][XXXX][X]\"\n" +
            "        }\n" +
            "    }\n" +
            "}";
        putMappingRequestBuilder.withJson(new StringReader(mappings));
        PutMappingRequest putMappingRequest = putMappingRequestBuilder.build();
        PutMappingResponse putMappingResponse = client.indices().putMapping(putMappingRequest);
        System.out.println(putMappingResponse);


Answered By - Tom Lever
Answer Checked By - Dawn Plyler (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, August 23, 2022

[FIXED] How to Magento 2 working with ElasticSearch

 August 23, 2022     elasticsearch, full-text-search, magento2     No comments   

Issue

I'm learning Magento 2. I have a project working with ElasticSearch, I don't know how exactly Magento 2 working with ElasticSearch. Could you please tell me how it works. Because I was confused between Sort By of Magento and Sort by Elastic.

  1. How exactly Sort By function work?

    1.1. The Collection of the product was sorted by Magento or ElasticSearch when I have sort by Price or Name?

  2. Does Magento support sort Product Collection using ElasticSearch?

  3. When Sorted by Relevance the product collection was sort by Elastic or Magento?

  4. If Magento doesn't support Sort Attribute using ElasticSearch what should I do to improve that

I have used Magento 2.1.3 & ElasticSearch 2.2 (Magento 2.1 doesn't work with the higher version)

Regards.

Thanks any típs.


Solution

For being short, Magento only support sort by score (relevance) with Elasticsearch for fulltext search.

The other sort options are performed after, during database query.

Indeed, even if a quite lot information are stored in ElasticSearch, Elasticsearch returns only a list of IDs - Score to Magento. Then Magento do a SQL request in order to load all information needed with the sort etc.

In order to sort by score, Magento create a temporary table with the result of ElasticSearch ID - Score to sort the Magento product collection.

But you can extend the module to add your complete feature.

So for answer your questions :

  • The Collection of the product was sorted by Magento or ElasticSearch when I have sort by Price or Name?

The sort is done on Magento side

  • Does Magento support sort Product Collection using ElasticSearch?

It doesnt support the native Elasticsearch sort feature. But can be extended. But the final result is ok.

  • When Sorted by Relevance the product collection was sort by Elastic or Magento?

The relevance (score) is performed by ElasticSearch and then stored to a temporary table and use in a JOIN SQL request.

  • If Magento doesn't support Sort Attribute using ElasticSearch what should I do to improve that

Extend the ElasticSearch SearchAdapter. I can help you on that. You need to build the sort values in the query based on your request. And then manage the sort values in the response.



Answered By - Franck Garnier
Answer Checked By - Cary Denson (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, January 14, 2022

[FIXED] What is the best database for full text search?

 January 14, 2022     full-text-search, lamp     No comments   

Issue

What is the best database for doing a fulltext search? Lucene and Sphinx are not an option, since the data in my case changes very frequently. Record count should be 250k+ entries, mostly product descriptions and similar. LAMP stack.


Solution

I suggest you open-source databases.

If you are serious about FTS in the long term and it is a very core feature of your product or application, I would suggest looking at Solr. If you are looking to implement simple FTS as a bolt-on to an existing PostgreSQL database, PostgreSQL FTS is a fantastic way to do this. PostgreSQL supports UTF8 and multiple languages for spelling, parsing, and stemming. MySQL only supports FTS on MyISAM tables and is really not very good for anything but the most very basic FTS implementation.

Source is here



Answered By - kamaci
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home
View mobile version

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing