Git Product home page Git Product logo

search-source's Introduction

search-source

Reactive Data Source for building search solutions with Meteor

If you are new to search source, it's a good idea to look at this introductory article on MeteorHacks.

Installation

meteor add meteorhacks:search-source

Creating a source in client

var options = {
  keepHistory: 1000 * 60 * 5,
  localSearch: true
};
var fields = ['packageName', 'description'];

PackageSearch = new SearchSource('packages', fields, options);
  • First parameter for the source is the name of the source itself. You need to use it for defining the data source on the server.
  • second arguments is the number of fields to search on the client (used for client side search and text transformation)
  • set of options. Here are they
    • keepHistory - cache the search data locally. You need to give an expire time(in millis) to cache it on the client. Caching is done based on the search term. Then if you search again for that term, it search source won't ask the server to get data again.
    • localSearch - allow to search locally with the data it has.

Define the data source on the server

In the server, get data from any backend and send those data to the client as shown below. You need to return an array of documents where each of those object consists of _id field.

Just like inside a method, you can use Meteor.userId() and Meteor.user() inside a source definition.

SearchSource.defineSource('packages', function(searchText, options) {
  var options = {sort: {isoScore: -1}, limit: 20};

  if(searchText) {
    var regExp = buildRegExp(searchText);
    var selector = {packageName: regExp, description: regExp};
    return Packages.find(selector, options).fetch();
  } else {
    return Packages.find({}, options).fetch();
  }
});

function buildRegExp(searchText) {
  var words = searchText.trim().split(/[ \-\:]+/);
  var exps = _.map(words, function(word) {
    return "(?=.*" + word + ")";
  });
  var fullExp = exps.join('') + ".+";
  return new RegExp(fullExp, "i");
}

Get the reactive data source

You can get the reactive data source with the PackageSearch.getData api. This is an example usage of that:

Template.searchResult.helpers({
  getPackages: function() {
    return PackageSearch.getData({
      transform: function(matchText, regExp) {
        return matchText.replace(regExp, "<b>$&</b>")
      },
      sort: {isoScore: -1}
    });
  }
});

.getData() api accepts an object with options (and an optional argument to ask for a cursor instead of a fetched array; see example below). These are the options you can pass:

  • transform - a transform function to alter the selected search texts. See above for an example usage.
  • sort - an object with MongoDB sort specifiers
  • limit - no of objects to limit
  • docTransform - a transform function to transform the documents in the search result. Use this for computed values or model helpers. (see example below)
Template.searchResult.helpers({
  getPackages: function() {
    return PackageSearch.getData({
      docTransform: function(doc) {
        return _.extend(doc, {
          owner: function() {
            return Meteor.users.find({_id: this.ownerId})
          }
        })
      },
      sort: {isoScore: -1}
    }, true);
  }
});

Searching

Finally we can invoke search queries by invoking following API.

PackageSearch.search("the text to search");

Status

You can get the status of the search source by invoking following API. It's reactive too.

var status = PackageSearch.getStatus();

Status has following fields depending on the status.

  • loading - indicator when loading
  • loaded - indicator after loaded
  • error - the error object, mostly if backend data source throws an error

Metadata

With metadata, you get some useful information about search along with the search results. These metadata can be time it takes to process the search or the number of results for this search term.

You can get the metadata with following API. It's reactive too.

var metadata = PackageSearch.getMetadata();

Now we need a way to send metadata to the client. This is how we can do it. You need to change the server side search source as follows

SearchSource.defineSource('packages', function(searchText, options) {
  var data = getSearchResult(searchText);
  var metadata = getMetadata();

  return {
    data: data,
    metadata: metadata
  }
});

Passing Options with Search

We can also pass some options while searching. This is the way we can implement pagination and other extra functionality.

Let's pass some options to the server:

// In the client
var options = {page: 10};
PackageSearch.search("the text to search", options);

Now you can get the options object from the server. See:

// In the server
SearchSource.defineSource('packages', function(searchText, options) {
  // do anything with options
  console.log(options); // {"page": 10}
});

Get Current Search Query

You can get the current search query with following API. It's reactive too.

var searchText = PackageSearch.getCurrentQuery();

Clean History

You can clear the stored history (if enabled the keepHistory option) via the following API.

PackageSearch.cleanHistory();

Defining Data Source in the Client

Sometime, we don't need to fetch data from the server. We need to get it from a data source aleady available on the client. So, this is how we do it:

PackageSearch.fetchData = function(searchText, options, success) {
  SomeOtherDDPConnection.call('getPackages', searchText, options, function(err, data) {
    success(err, data);
  });
};

search-source's People

Contributors

arunoda avatar chip avatar kueblboe avatar markshust avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

search-source's Issues

Searching for other value types than strings

First of all: I really like this package, it helps a lot to implement search functionality.

Today, I tried to set-up a search that uses an array of strings instead of a plain string as an input parameter. This did not work. Instead, I got the following error message:

I20151106-13:55:32.616(1)? Exception while invoking method 'search.source' Error: Match error: Failed Match.OneOf or Match.Optional validation
I20151106-13:55:32.616(1)?     at checkSubtree (packages/check/match.js:244:1)
I20151106-13:55:32.616(1)?     at check (packages/check/match.js:32:1)
I20151106-13:55:32.617(1)?     at [object Object].Meteor.methods.search.source (packages/meteorhacks:search-source/lib/server.js:12:1)
I20151106-13:55:32.617(1)?     at [object Object].methodMap.(anonymous function) (packages/meteorhacks:kadira/lib/hijack/wrap_session.js:164:1)
I20151106-13:55:32.617(1)?     at packages/check/match.js:109:1
I20151106-13:55:32.617(1)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20151106-13:55:32.617(1)?     at Object.Match._failIfArgumentsAreNotAllChecked (packages/check/match.js:108:1)
I20151106-13:55:32.617(1)?     at maybeAuditArgumentChecks (packages/ddp/livedata_server.js:1614:1)
I20151106-13:55:32.617(1)?     at packages/ddp/livedata_server.js:648:1
I20151106-13:55:32.617(1)?     at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
I20151106-13:55:32.617(1)? Sanitized and reported to the client as: Match failed [400]
I20151106-13:55:32.617(1)? 

Is there any particular reason why the input parameter is limited to a string? I will now concat the array using a delimiter character as a work-around, but it would be nicer if I could send arrays or plain objects directly.

Metadata

Hi,
I tried to use the API getMetadata to get the number of results for a certain search but I can get it working. Could you provide a working example?

I defined an helper:

Template.toursSearchResults.helpers({
  meta: function() {
    console.log("METADATA: " + TourSearch.getMetadata());
    return TourSearch.getMetadata();
  }
});

I defined a server searchSource:

SearchSource.defineSource('tours', function(searchText, options) {
  var options = {sort: {submitted: -1}, limit: 20};
  if(searchText) {
   var regExp = buildRegExp(searchText);
   var selector = {$or: [
     {title: regExp},
     {summary: regExp}
   ]};
   return Tours.find(selector, options).fetch();
//  var data = getSearchResult(searchText);
//  var metadata = getMetadata();

//  return {
//    data: data,
//    metadata: metadata
//  }
 } else {
   return Tours.find({}, options).fetch();
 }
});

function buildRegExp(searchText) {
  // this is a dumb implementation
  var parts = searchText.trim().split(/[ \-\:]+/);
  return new RegExp("(" + parts.join('|') + ")", "ig");
}

And i am calling the search in the helper at the keyup as in you example:

Template.toursSearchBox.events({
  "keyup #search-box": _.throttle(function(e) {
    var text = $(e.target).val().trim();
    TourSearch.search(text);
  }, 200)
});

But i cannot get the metadata. In the browser console i get an empty metadata object. If i uncomment the getMetadata() call in the searchSource server side definition I get a getMetadata is not defined.

Could you help me understand where is the error?

Thank you for your great job!

Sub packages not added automatically

I had an issue getting this package working.

Turns out that when I "meteor add search:source" for some reason the "check" and "ejson" packages were not added.

I'm not sure if this is something I did wrong or how the package is erm packaged!

I'm putting this here for other users who may be facing a similar issue

Using search-source for autocomplete with input forms

What would be the best strategy to create a dropbown autocomplete for form input fields with search-source?

Similar to Select2, but just for a regular input.

This takes data from Google, but I am just talking about the styling of searching my own data and then putting results in a dropdown to insert in a form that will be submitted:
https://github.com/comerc/meteor-autoform-placecomplete/

This package is close, but is missing your search-source features of bolding the text that matches:
https://github.com/miguelalarcos/afwrap-xautocomplete/

It seems I would be able to put the search results right under the form field input, have it floating with css, and then make arrow key functionality/ clicking functionality, then have it disappear.

But I don't want to reinvent the wheel, is there a better way?

Example, I have an address form with inputs:
Customer
Company
Street1
Street2
City
State
Zip

And I want to search my Addresses collection on each of those fields, with a similar interface to select2 where the search results are right under the form field temporarily, I select one with arrow keys or the mouse, and then it inserts that value in the form.

Any ideas?

Thank you.

Reactive getData() causes helper to be executed 3 times

I'm using getData() as described in the docs, as part of a helper. I've noticed that this helper is run three times (instead of one time), if a new search is executed. This causes problems, because I would like to animate the display of the results. If you don't animate it, you won't notice the 3 renderings, but if you animate, you do. What may cause these multiple calls?

Question: Search in _id mongoDB

I would like to search in an input search box for the _id so it can be displayed in the results. Any ideas how to achieve this? I am new to meteor, btw.

 var selector = {name: regExp, _id: regExp};

What is the purpose of 'isoScore' in the sort options

Hi @arunoda,

I tried to look in the docs for what isoScore does but could not find it. Is it something that is used internally? Is it used to indicate the search weight-age and provide more importance to some fields?

PS. Thanks for the awesome package (and the million other things you did for the Meteor community :)

Return another data except array

I want something like this:

SearchSource.defineSource 'items', (text, options) ->
    selector = {}

    if text
        regExp = buildRegExp text
        selector =
            name: regExp

    result = 
        items: Items.find(selector, options).fetch()
        count: Items.find(selector).count()

    return result

Integration with reywood:publish-composite package

Maybe this is a dumb question, but i saw in the examples there is a transformDoc property which can be used to modify the docs.

Is there a way to skip this and return a publish function instead?

I have a Collection named post which has a postThumbnail property, which is a reference to a document in Files.files collection. I return every post thumbnail using publishComposite publication on server, so it will be awesome if instead of returning a cursor, i could specify a named publication, something like:

SearchSource.defineSource('posts', function(searchText, options) {
    // ...
    return namedPublication('allposts' , searchText , options); 
});

Meteor.publishComposite('allposts', function(searchText, options){
  return {
    find : function(){ return Posts.find(); },
    children : [
    {
       find: function(post){ 
           if (!post.adThumbnail) return;
           return Files.files.find({_id:post.adThumbnail});
       }
    }
    ]
  }
});

I know problem can be solved using transformDoc but who knows, maybe this is possible.

Exception while invoking method 'search.source' Error: Match error: Failed Match.OneOf or Match.Optional validation

Hello. I'm trying to implement this package but have an error:

Exception while invoking method 'search.source' Error: Match error: Failed Match.OneOf or Match.Optional validation
    at check (packages/check/match.js:33:1)
    at [object Object]._.extend._getFindOptions (packages/mongo/collection.js:248:1)
    at [object Object]._.extend.find (packages/mongo/collection.js:284:1)
    at [object Object].<anonymous> (server/search-source.js:7:1)
    at [object Object].getSourceData (packages/meteorhacks_search-source/lib/server.js:65:1)
    at [object Object].Meteor.methods.search.source (packages/meteorhacks_search-source/lib/server.js:18:1)
    at maybeAuditArgumentChecks (livedata_server.js:1698:12)
    at livedata_server.js:708:19
    at [object Object]._.extend.withValue (packages/meteor/dynamics_nodejs.js:56:1)
    at livedata_server.js:706:40
Sanitized and reported to the client as: Match failed [400]

Here is my code.
Client

var options = {
    keepHistory: 1000 * 60 * 5,
    localSearch: true
};
var fields = ['exerciseName', 'exerciseDesc'];

ExercisesSearch = new SearchSource('exercises', fields, options);

Server

SearchSource.defineSource('exercises', function(searchText, options) {
    //var options = {sort: {isoScore: -1}, limit: 20};

    if(searchText) {
        var regExp = buildRegExp(searchText);
        var selector = {exerciseName: regExp, exerciseDesc: regExp};
        return Exercises.find(selector, options).fetch();
    } else {
        return Exercises.find({}, options).fetch();
    }
});

function buildRegExp(searchText) {
    var words = searchText.trim().split(/[ \-\:]+/);
    var exps = _.map(words, function(word) {
        return "(?=.*" + word + ")";
    });
    var fullExp = exps.join('') + ".+";
    return new RegExp(fullExp, "i");
}

FR: Merge search results with local collection

This would be a great feature:

If my ES type, for example items, is a mirror of a Mongo collection Items, it would be great if SearchSource could add the search results to the local client Items._collection so that I can do Items.find x and get results that were either published OR found through an ES search.

Searching a sub array and only outputting the matching data

I have a collection

marks {
   testers: {
        {
           "class": "math",
           "mark": 81
        },
        {
           "class": "english",
           "mark": 90
        }

    }
}

So, my server method is

SearchSource.defineSource('packages', function(searchText, options) {
    console.dir(searchText);
    if(searchText) {
      var regExp = buildRegExp(searchText);
      var options = {limit: 20};
        var selector = {"testers.class": regExp}

        return marks.find(selector, options).fetch();
      }

    } else {
        return marks.find({}, options).fetch();
    }
  });

This returns every single 'class' object if one of them matches the search query. If I search "english", I want it to just return the word 'english'. How can I do this?

Is it possible to use search-source with a few collections at once?

I have to implement global search in my app. It should show search results from Clients, Projects, Orders and Suppliers collections into one list.

Is search-source good choice to do that? If yes, any examples? If not, then also ok, I will just look for some other solutions... ;)

Thanks for any answers.

invoking 'search.source': Error: Internal server error [500]...Help please!

Exception in delivering result of invoking 'search.source': Error: Match failed [400]

Not sure where to even start with this one. Any ideas?

SearchSource.defineSource("bookings", function(searchText, options) {
      var options = (typeof options == "object") ? options : { sort: { isoScore: -1 }, limit: 20 };

      if(searchText) {

        var regExp = new RegExp("(" + searchText.trim().split(" ").join("|") + ")", "ig");

        console.info(searchText, regExp);

        var selector = { $or: [
          { customer: regExp },
          { notes: regExp }
        ]};

        return Bookings.find(selector, options).fetch();

      }
      else {

        return Bookings.find({}, options).fetch();

      }

    });

Denormalized data

Is it possible to search on denormalized date, for example cities and then show me the parent documents, or even better search on both ?

thanks in advance..

_buildRegExp does not work when you have custom analyzer filters like asciifolding

Problem is with the following code in client.js (and especially the _buildRegExp function):

  // only do client side searching if we are on the loading state
  // once loaded, we need to send all of them
  if(this.getStatus().loading) {
    self.searchFields.forEach(function(field) {
      var singleQuery = {};
      singleQuery[field] = regExp;
      selector['$or'].push(singleQuery);
    });
  } else {
    selector = {};
  }

If my query is "oeuf" and cached results contain a field value "œuf" (note the œ), when the search will be in "loading" state, "œuf" will disappear, until the search will switch in "loaded" state.

Weird behavior of getData()

Demo page: http://cornellcoursereview.meteor.com/

My code:

if (Meteor.isServer) {
  SearchSource.defineSource('courses', function(searchText, options) {
    var options = {
      fields: {'catalog':1, 'titleLong':1, 'catalogNbr':1},
      limit: 10
    };

    if(searchText) {
      var regExp = buildRegExp(searchText);

      var selector = {$or: [
        {titleLong: { $regex: regExp } },
        {catalog: { $regex: regExp } },
        {catalogNbr: { $regex: regExp } }
      ]}

      return Courses.find(selector, options).fetch();
    } else {
      console.log("couldn't find anything that suits the query");
      console.log("query:", searchText);
      return Courses.find({}, options).fetch();
    }
  });

  function buildRegExp(searchText) {
    var words = searchText.trim().split(/[ \-\:]+/);
    var exps = _.map(words, function(word) {
      return "(?=.*" + word + ")";
    });
    var fullExp = exps.join('') + ".+";
    return new RegExp(fullExp, "i");
  }
}

query = "intro algo" matches with "introduction to analysis of algorithms"
If you go to the demo url, you will see that although the document is found, it's rendered in a weird way.

Type into algo first, then press any function key like alt, cmd, or ctrl. You will see that the result disappears and appears intermittently.

Set breakpoints inside getData() and you will see that it returns an empty object even though there's fetch data.

get reactive data.

Package does not return reactive data. I've forked your example app, searched for a particular package, edited the 'packageName' in mongo. The data in the app will not update until I re-query the search.

Please advise.

Exception in delivering result of invoking 'search.source'

This is very frustrating, because this is the first addon I try and it simply doesn´t work.
Console keeps telling me "Exception in delivering result of invoking 'search.source': Error: Internal server error [500]" each time I try to give it a try. The full stack is this:

Exception in delivering result of invoking 'search.source': Error: Internal server error [500]
at .extend.livedata_result (http://localhost:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:4625:23)
at onMessage (http://localhost:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:3365:12)
at http://localhost:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:2734:11
at Array.forEach (native)
at Function.
.each.
.forEach (http://localhost:3000/packages/underscore.js?46eaedbdeb6e71c82af1b16f51c7da4127d6f285:149:11)
at self.socket.onmessage (http://localhost:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:2733:11)
at REventTarget.dispatchEvent (http://localhost:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:173:22)
at SockJS._dispatchMessage (http://localhost:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:1158:10)
at SockJS._didMessage (http://localhost:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:1216:18)
at WebSocket.that.ws.onmessage (http://localhost:3000/packages/ddp-client.js?250b63e6c919c5383a0511ee4efbf42bb70a650f:1363:17)

Cannot read property '_str' of undefined

Filtering/Sort

If I wanted to let the user filter or change sort, is that doable with search-source? Would be good to have some mention of this on the wiki as I prefer the implementation of this over easysearch but would like to be able to filter/sort

Allow search for a term with multiple words

For example, "Search Source" would give matches for "Search", "Source", and "Search Source". Is there a way to restrict the search so that it only gives matches for the whole phrase, "Search Source"?

Transform highlighting doesn't work on _id

If I use this transform function for highlighting search results:

transform: function(matchText, regExp) {
    console.log(matchText, regExp);
    return matchText.replace(regExp, "<b>$&</b>");
},

And I use '_id' as one of the search fields, I get the following error when I search:

Exception in template helper: Error: transformed document can't have different _id
    at wrapped [as _transform] (http://localhost:3000/packages/minimongo.js?hash=9b1463853801ce7302ecca3eac339c514a0341db:1174:15)
    at http://localhost:3000/packages/minimongo.js?hash=9b1463853801ce7302ecca3eac339c514a0341db:200:18
    at Array.forEach (native)
    at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?hash=8de51f9d86e95ae2ffee15a8db324a1decccba3e:139:11)
    at LocalCollection.Cursor.forEach (http://localhost:3000/packages/minimongo.js?hash=9b1463853801ce7302ecca3eac339c514a0341db:195:5)
    at LocalCollection.Cursor.fetch (http://localhost:3000/packages/minimongo.js?hash=9b1463853801ce7302ecca3eac339c514a0341db:238:8)
    at SearchSource.getData (http://localhost:3000/packages/meteorhacks_search-source.js?hash=0b4c91bf433d5d896a2beba7db436da54fc8f842:184:17)
    at Object.invoices (http://localhost:3000/app/app.js?hash=476b27c1277f65d46aa8bc18f3c3d4243f7322ec:1049:45)
    at http://localhost:3000/packages/blaze.js?hash=38069f4f7cfbd8898160bc97d37dd847cd5985fe:2984:16
    at http://localhost:3000/packages/blaze.js?hash=38069f4f7cfbd8898160bc97d37dd847cd5985fe:1643:16

Is there any way to get _id searching / transforming to work?

Nested fields

I am trying to use this package to search in nested fields of a document but it seems to cause a problem with the transform function on the client. (maybe by accessing the document fields like

 doc[field]

is causing the issue ?)

I am not really a js guy so I might be completely out.

Wich notation should we use to define the search in nested fields ?

Transform method not hit in .getData

Greetings! I'm working through your example (thank you) however running into problems getting the transform to fire.

The docTransform hits every time. But never the transform.

Any ideas?

`Template.SearchResults.helpers({
offender: function() {

return OffenderSearch.getData({
  transform: function (matchText, regExp) {
    console.log('hit transform');
    return matchText.replace(regExp, "<b>$&</b>");
  },

  docTransform: function(doc) {
    console.log('hit docTransform');
    return doc;
  }
});

}`

Elasticsearch

Can I define an elasticsearch result source?

I've tried with npm elasticsearch plugin but it seems that "body.hits.hits" doesn't match the expecting return type.

Exception in delivering result of invoking 'search.source': TypeError: Cannot read property 'data' of undefined

Hi,

I am trying to use Searchsource in my Meteor Angular project.
The implementation as I used to do it in my meteor only project with Blaze seems to work, however on page load I get this error message:
Exception in delivering result of invoking 'search.source': TypeError: Cannot read property 'data' of undefined

My code:

angular.module( 'myapp' ).controller 'feedListCtrl',
  ($scope, $meteor, $state , $stateParams ) ->

    feedName = $stateParams.term
    limit = 30
    sort =
      'publishedDate': -1

    $scope.channelData = null
    $scope.episodes = null
    $scope.channelLoading = true
    $scope.episodeCount = 0
    $scope.activeListItem = null

    $scope.channel  = $meteor.subscribe( 'channelMetaByName', feedName )
    $scope.feed     = $meteor.subscribe( 'feedsByChannelName', feedName, sort )



    # $scope.feed     = $meteor.collection( Feeds, false ).subscribe( 'feedsByChannelName', feedName, sort )
    # $scope.channel  = $meteor.collection( Channels, false ).subscribe( 'channelMetaByName', feedName )

    $scope.channel.then ( subscription )->
      $scope.channelLoading   = false
      $scope.channelData      = Channels.findOne().channelMeta


    $scope.feed.then ( subscription ) ->
      $scope.episodes = Feeds.find().fetch()
      $scope.episodeCount = Feeds.find().count()

    $meteor.autorun $scope, ->
      console.log("search", $scope.getReactively( 'search' ) )
      FeedSearch.search $scope.getReactively( 'search' )

Besides the error message, the search does work in the autorun part. When I call getData I do get the filtered results.
Any idea what is going wrong?

Search with mongo-like selectors

Apparently search is only possible with a single textual keyword. I wonder if I am right and if there is any reason for this design choice. Do you think a generic search using a kind of Mongodb query selector would make sense?

Thanks

transform issue of matched text

If one of the searchable fields is an array this code doesn't work:
return PackagesSearch.getData({
transform: function(matchText, regExp) {

    return matchText.replace(regExp, "<b>$&</b>")
   },
   sort: {date: -1}
});

astronomy conflict

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.