Neurophysiologically Pseudoscientific Manatee

    node-suggestive-search

    1.10.6 • Public • Published

    Node suggestive search

    Don't let spelling mistakes prevent your users from finding what they were looking for! This node module was built to help type-ahead and dropdown search boxes and also correct misspelled searches (did you mean?).

    This module is compatible with:

    Installation, tests

    Module name on npm is "node-suggestive-search".

    npm install node-suggestive-search --save   # Install the latest version in your project
    

    Example of usage

    https://node-suggestive-search.herokuapp.com

    API

    Setting options

    This module supports Redis, MongoDB and NeDB but you can use an in-memory volatile cache.

    Configuration without database (in-memory):

    var nss = require('node-suggestive-search').init();
     

    Configuration without database with cache (in-memory):

    var nss = require('node-suggestive-search').init({ cache: true });
     

    Configuration using Redis:

    var nss = require('node-suggestive-search').init(
                {
                dataBase: "redis", 
                redisDatabase: "redis://localhost:6379",
                cache: true
                });
     

    Configuration using MongoDB:

    var nss = require('node-suggestive-search').init(
                {
                dataBase: "mongodb", 
                mongoDatabase: "mongodb://127.0.0.1:27017/nodeSugestiveSearch",
                cache: true
                });
     

    Configuration using NeDB with a datafile:

    var nss = require('node-suggestive-search').init(
                {
                dataBase: "nedb", 
                neDbDataPath: "dataFolder",
                neDbInMemoryOnly: false,
                cache: true
                });
     

    Configuration using NeDB without a datafile (in-memory):

    var nss = require('node-suggestive-search').init(
                {
                dataBase: "nedb", 
                neDbDataPath: "",
                neDbInMemoryOnly: true,
                cache: false
                });
     

    There is also an option to include stop-words:

    var nss = require('node-suggestive-search').init(
                {
                stopWords: ["1033", "1046", ..., __dirname + "\\yourOwnStopWords.json"]
                });
                
    //current built-in available stopwords dictionary
    //1033 - en-us - English - United States
    //1036 - fr-fr - French - France
    //1040 - it-it - Italian - Italy
    //1046 - pt-br - Portuguese - Brazil
    //1048 - ro    - Romanian - Romania
    //2057 - en-gb - English - Great Britain
    //2070 - pt-pt - Portuguese - Portugal
     

    The "cache" option enables an in-memory copy of the data structure boosting the performance. Turn off this option if you have more than one instance accessing the same database.

    Loading a database

    Build a dictionary composed by items and words that need to be searched.

    Example of a JSON to be imported (Items.json):

    [  
       {  
          "itemName":"WHISKY RED LABEL",
          "itemId":"1",
          "keywords":"FANCY" 
       },
       {  
          "itemName":"WHISKY BLACK LABEL",
          "itemId":"2",
          "keywords":"EXPENSIVE"
       },
       {  
          "itemName":"BLACK FOREST LABELY HAM L/S",
          "itemId":"3"
       },
       {  
          "itemName":"PESTO PARMESAN HAM",
          "itemId":"4"
       },
       {  
          "itemName":"DELI SWEET SLICE SMOKED HAM",
          "itemId":"5"
       }  
    ]

    Load the JSON from file

    //you can change the charset to match your file
    nss.loadJson("Items.json", "utf8").then(data => {
        // response: { words: 17, items: 5, timeElapsed: '4ms' }
    });
     

    Load the JSON from file with your properties names

     
    nss.loadJson("Items.json", "utf8", "itemId", "itemName", "keywords").then(data => {
        // response: { words: 17, items: 5, timeElapsed: '3ms' }
    });
     

    Load the JSON from string

     
    let jSonString = `[{"itemName":"WHISKY RED LABEL", "itemId":"1", "keywords": "fancy"},{  
                        "itemName":"WHISKY BLACK LABEL", "itemId":"2"}]`;
     
    nss.loadJsonString(jSonString).then(data => {
        // response: { words: 5, items: 2, timeElapsed: '1ms' }
    });
     

    Load the JSON from string with additional fields (price, popularity and thumbImg). You can insert any additional field excluding itemId, itemName and keywords.

     
    let jSonString = `[{"itemName":"WHISKY RED LABEL", "itemId":"1", "keywords":"fancy", "price":25.57, "popularity":1, "thumbImg":"whisky-red-label.png"},{  
                        "itemName":"WHISKY BLACK LABEL", "itemId":"2", "price":19.99, "popularity":0.9, "thumbImg":"whisky-black-label.png"}]`;
     
    nss.loadJsonString(jSonString).then(data => {
        // response: { words: 5, items: 2, timeElapsed: '2ms' }
    });
     

    Load the JSON from string with your properties names

     
    let jSonString = `[{"nm":"WHISKY RED LABEL", "id":"1", "kw": "fancy"},{  
                        "nm":"WHISKY BLACK LABEL", "id":"2"}]`;
     
    nss.loadJsonString(jSonString, "id", "nm", "kw").then(data => {
        // response: { words: 5, items: 2, timeElapsed: '2ms' }
    });
     

    Load the JSON from string with your properties names and additional fields (price, popularity and thumbImg). You can insert any additional field excluding itemId, itemName and keywords.

     
    let jSonString = `[{"nm":"WHISKY RED LABEL", "id":"1", "kw":"fancy", "price":25.57, "popularity":1, "thumbImg":"whisky-red-label.png"},{  
                        "nm":"WHISKY BLACK LABEL", "id":"2", "price":19.99, "popularity":0.9, "thumbImg":"whisky-black-label.png"}]`;
     
    nss.loadJsonString(jSonString, "id", "nm", "kw").then(data => {
        // response: { words: 5, items: 2, timeElapsed: '2ms' }
    });
     

    Searching for items

    Getting itemsId from searched words.

    Examples of how to call the api and responses:

     
    nss.query("whisky").then(data => {
        //response:  { query: 'whisky', words: [ 'whisky' ], missingWords: [], expressions: [], missingExpressions: [], itemsId: [ '1', '2' ], timeElapsed: '1ms' }
    });
     
    //did you mean search result with misspelled search criteria
    nss.query("wisk").then(data => {
        //response: { query: 'wisk', words: [ 'whisky' ], missingWords: ['wisk'], expressions: [], missingExpressions: [], itemsId: [ '1', '2' ], timeElapsed: '1ms' }
    });
     
    //did you mean search result with misspelled search criteria
    nss.query("wisk read lbel").then(data => {
        //response: { query: 'Wisk Read Labl', words: [ 'Whisky', 'Red', 'Label' ], missingWords: ['Wisk', 'Read', 'Labl'], expressions: [], missingExpressions: [], itemsId: [ '1' ], timeElapsed: '2ms' }
    });
     
    //query with paramenter returnItemsJson = true  
    nss.query("whisky", true).then(data => {
        /*response:  { query: 'whisky', words: [ 'whisky' ], missingWords: [], expressions: [], missingExpressions: [], 
            [ 
                { itemName: 'WHISKY RED LABEL', itemId: '1', keywords: 'fancy' },
                { itemName: 'WHISKY BLACK LABEL', itemId: '2' } 
            ], 
            timeElapsed: '1ms' }
        */
    });
     
    //query with paramenter returnItemsJson = true and ordering by popularity, desc using an object on a database loaded with additional fields
    let orderByObject = {field: "popularity", direction: "desc"};
     
    nss.query("whisky", true, orderByObject).then(data => {
        /*response:  { query: 'whisky', words: [ 'whisky' ], missingWords: [], expressions: [], missingExpressions: [], 
            [ 
                { itemName: 'WHISKY RED LABEL', itemId: '1', keywords: 'fancy', price: 25.57, popularity: 1, thumbImg: 'whisky-red-label.png' },
                { itemName: 'WHISKY BLACK LABEL', itemId: '2', price: 19.99, popularity: 0.9, thumbImg: 'whisky-black-label.png' } 
            ], 
            timeElapsed: '1ms' }
        */
    });
     
    //query with paramenter returnItemsJson = true and ordering by popularity, desc using a function on a database loaded with additional fields
    let orderByFunc = ((x, y) => { return x.popularity < y.popularity; });
     
    nss.query("whisky", true, orderByFunc).then(data => {
        /*response:  { query: 'whisky', words: [ 'WHISKY' ], missingWords: [], expressions: [], missingExpressions: [], 
            [ 
                { itemName: 'WHISKY RED LABEL', itemId: '1', keywords: 'fancy', price: 25.57, popularity: 1, thumbImg: 'whisky-red-label.png' },
                { itemName: 'WHISKY BLACK LABEL', itemId: '2', price: 19.99, popularity: 0.9, thumbImg: 'whisky-black-label.png' } 
            ], 
            timeElapsed: '1ms' }
        */
    });
     
    //quoted search criteria
    nss.query("'red label'").then(data => {
        //response: { query: '\'RED LABEL\'', words: [ 'RED', 'LABEL' ], missingWords: [], expressions: [ 'RED LABEL' ], missingExpressions: [], itemsId: [ '1' ], timeElapsed: '1ms' }
    });
     
    //quoted search criteria
    nss.query("'label red'").then(data => {
        //response: { query: '\'label red\'', words: [ 'label', 'red' ], missingWords: [], expressions: [], missingExpressions: [ 'label red' ], itemsId: [ '1' ], timeElapsed: '2ms' }
    });
     
    //dashed search criteria
    nss.query("Red-Blood").then(data => {
        //response: { query: 'Red-Blood', words: [ 'Red' ], missingWords: [ 'Blood' ], expressions: [], missingExpressions: [ 'Red-Blood' ], itemsId: [ '1' ], timeElapsed: '2ms' }
    });
     
    //slashed search criteria
    nss.query("HAM L/S").then(data => {
        //response: { query: 'HAM L/S', words: [ 'HAM', 'L', 'S' ], missingWords: [], expressions: [ 'L/S' ], missingExpressions: [], itemsId: [ '3' ], timeElapsed: '2ms' }
    });
     
    //double quoted search criteria
    nss.query("\"HAM L/S\"").then(data => {
        //response: { query: '"HAM L/S"', words: [ 'HAM', 'L', 'S' ], missingWords: [], expressions: [ 'HAM L/S' ], missingExpressions: [], itemsId: [ '3' ], timeElapsed: '2ms' }
    });
     
      

    Getting words suggestions

    Getting words suggestions to fill dropdown boxes or type-ahead text fields.

    Examples of how to call the api and responses:

     
    nss.getSuggestedWords("La").then(data => {
        //response: { suggestions: [ 'Label', 'Labely' ], timeElapsed: '1ms' }
    });
     
    nss.getSuggestedWords("whi").then(data => {
        //response: { suggestions: [ 'whisky label', 'whisky red', 'whisky black' ], timeElapsed: '1ms' }
    });
     
    nss.getSuggestedWords("whisky re").then(data => {
        //response: { suggestions: [ 'whisky red' ], timeElapsed: '2ms' }
    });
      

    Getting items suggestions

    Getting items suggestions to fill dropdown boxes or type-ahead text fields.

    Examples of how to call the api and responses:

     
    nss.getSuggestedItems("PARME").then(data => {
        //response: { items: [ { itemId: '4', itemName: 'PESTO PARMESAN HAM' } ], timeElapsed: '2ms' }
    });
     
    nss.getSuggestedItems("Whisky fancy").then(data => {
        //response: { items: [ { itemId: '1', itemName:'WHISKY RED LABEL' } ], timeElapsed: '1ms' }
    });
     
    nss.getSuggestedItems("whisky re").then(data => {
        //response: { items:[ { itemId: '1', itemName: 'WHISKY RED LABEL' } ], timeElapsed: '1ms' }
    });
     
    nss.getSuggestedItems("whisky label").then(data => {
        //response: { items: [ {itemId: '1', itemName: 'WHISKY RED LABEL' }, { itemId: '2', itemName: 'WHISKY BLACK LABEL' } ], timeElapsed: '2ms' }
    });
     
    //get one item suggestions ordering by price, asc using a function and omitting the direction.
    let orderByObject = {field: "price"};
     
    nss.getSuggestedItems("whisky label", 1, orderByObject).then(data => {
        //response: { items: [ { itemName: 'WHISKY BLACK LABEL', itemId: '2', price: 19.99, popularity: 0.9, thumbImg: 'whisky-black-label.png' } ], timeElapsed: '2ms' }
    });
      
    //get one item suggestions ordering by price, asc using a function.
    let orderByFunc = ((x, y) => { return x.price > y.price; });
     
    nss.getSuggestedItems("whisky label", 1, orderByFunc).then(data => {
        //response: { items: [ { itemName: 'WHISKY BLACK LABEL', itemId: '2', price: 19.99, popularity: 0.9, thumbImg: 'whisky-black-label.png' } ], timeElapsed: '2ms' }
    });
      
      

    Insert items

    Insert a new item into the database.

    Examples of how to call the api and responses:

     
    let newItem = {  
        "itemId": "VODKA ABSOLUT",
        "itemName": "6",
        "keywords": "Keyword1, keyword2..."
        };
     
    nss.insertItem(newItem).then(data => {
        //response: { timeElapsed: '2ms' }
    });
     

    Insert an item with your properties names.

     
    let newItem = {  
        "id": "VODKA ABSOLUT",
        "nm": "6",
        "kw": "Keyword1, keyword2..."
        };
     
    nss.insertItem(newItem, "id", "nm", "kw").then(data => {
        //response: { timeElapsed: '2ms' }
    });
     

    Insert an item with additional fields (price, popularity and thumbImg). You can insert any additional field excluding itemId, itemName and keywords.

     
    let newItem = {  
        "itemId": "VODKA ABSOLUT",
        "itemName": "6",
        "keywords": "Keyword1, keyword2...",
        "price": 25.57,
        "popularity": 1,
        "thumbImg": "vodka-absolute.png"
        };
     
    nss.insertItem(newItem).then(data => {
        //response: { timeElapsed: '2ms' }
    });
     

    Remove items

    Remove an item from the database.

    Examples of how to call the api and responses:

     
    let itemId = "6";
     
    nss.removetItem(itemId).then(data => {
        //response: { timeElapsed: '2ms' }
    });
     

    Roadmap

    • Catalog (several dictionaries)
    • More databases support
    • Inject your database plugin
    • Browser version.
    • Translate JS to TS

    Pull requests

    If you submit a pull request, thanks! There are a couple of rules to follow to make it manageable:

    • The pull request should be atomic, i.e. contain only one feature. If it contains more, please submit multiple pull requests.
    • Please stick to the current coding style. It's important that the code uses a coherent style for readability.
    • Update the readme accordingly.
    • Last but not least: The goal here is simplicity.

    Bug reporting guidelines

    If you report a bug, thank you! That said for the process to be manageable please strictly adhere to the following guidelines. I'll not be able to handle bug reports that don't:

    • Your bug report should be a self-containing project with a package.json for any dependencies you need. I need to run through a simple npm install; node bugreport.js.
    • It should use assertions to showcase the expected vs actual behavior.
    • Simplify as much as you can. Strip all your application-specific code.
    • Please explain precisely in the issue.
    • The code should be Javascript.

    Donations

    Please consider donating some if your app is successful or you learned something valuable here.

    paypal

    Keep in mind that I am maintaining this repository on my free time so thank you for considering a donation. 👍

    Install

    npm i node-suggestive-search

    DownloadsWeekly Downloads

    27

    Version

    1.10.6

    License

    MIT

    Unpacked Size

    4.26 MB

    Total Files

    24

    Last publish

    Collaborators

    • ivanvaladares