Search code examples
jqueryajaxnode.jsmongoosastic

How to stop duplication on instant search? jquery + AJAX + mongoosastic


Currently The instant search that I'm using is working perfectly but , there is only one problem.

Whenever I type "Chemical", it will show the query for

Chemical Engineer
Chemical Entrepreneur
Checmical People

But let say I decided to add "Engineer" after "Chemical", then the result will be

Chemical Engineer
Chemical Entrepreneur
Checmical People
Chemical Engineer
Chemical Entrepreneur
Checmical People

Here's the code

router.js

router.post('/api/search/', function(req, res, next) {

  Product.search(
    {
      query_string:
      { query: req.body.search_term }
    } , function(err, results) {
        if (err) return next(err);
        res.json(results);
    });
});

custom.js

$('#search').keyup(function() {

    // 1. grab the search term from the input field
    var search_term = $(this).val();

    // 2. send it to your back-end via ajax in the body
    $.ajax({
      method: "POST",
      url: "/api/search",            // <-- your back-end endpoint
      data: { search_term },  // <-- what you're sending
      dataType: "json",              // <-- what you're expecting back
      success: function(json){       // <-- do something with the JSON you get
        // 3. parse the JSON and display the results
        var res = json.hits.hits.map(function(hit) {
          return hit;
        });
        console.log(res);
        for (var i = 0; i < res.length; i++) {
          $('.testing').append('<li>' + res[i]._source.name + '</li>');
        }

      },
      error: function(data){
        alert('Error', data);
      }
    });
  });

How do i stop duplication?

after using curl -XGET localhost:9200/products/_mapping suggested by Val

{"products":{"mappings":{"product":{"properties":{"_id":{"type":"string"},"category":{"type":"string"},"description":{"type":"string"},"image":{"type":"string"},"name":{"type":"string"},"price":{"type":"double"},"sizes":{"type":"string"},"stocks":{"type":"double"}}}}}}

Solution

  • I think you should clean previus results. Always you press a key you get the value of textfield and that value will be sent through ajax. If you write Chemical you will get some responses which will be appended to your html, all those responses matched with Chemical so when you write Chemical Engineering you need to clean up previus appended tags so I think this could be enough:

    custom.js

    $('#search').keyup(function() {
    
        // 1. grab the search term from the input field
        var search_term = $(this).val();
    
        // 2. send it to your back-end via ajax in the body
        $.ajax({
          method: "POST",
          url: "/api/search",            // <-- your back-end endpoint
          data: { search_term },  // <-- what you're sending
          dataType: "json",              // <-- what you're expecting back
          success: function(json){       // <-- do something with the JSON you get
            // 3. parse the JSON and display the results
            var res = json.hits.hits.map(function(hit) {
              return hit;
            });
            console.log(res);
            $('.testing').empty(); ///new line added
            for (var i = 0; i < res.length; i++) {
              $('.testing').append('<li>' + res[i]._source.name + '</li>');
            }
    
          },
          error: function(data){
            alert('Error', data);
          }
        });
      });
    

    PS: The sentence var search_term = $(this).val(); is not necessary keyup function gives you through parameter the event with the element

    https://api.jquery.com/keyup/