【问题标题】:How to search js-data resources with Lunr on angular?如何在 Angular 上使用 Lunr 搜索 js-data 资源?
【发布时间】:2015-12-24 17:38:07
【问题描述】:

在我的 Angular (1.3) 应用程序中,我使用的是 JSData (2.0.0),我想使用 Lunr 为这些资源添加全文搜索功能,而不使用 Ajax。有什么建议吗?

【问题讨论】:

    标签: angularjs jsdata lunrjs


    【解决方案1】:

    为此,我创建了 JSData 的 DS 资源的 SearchableDS 扩展。

    这是一个用法示例:

    angular.module("app")
    
    .factory("User", function(SearchableDS) {
      var resource;
      // so far the same JSData code
      resource = SearchableDS.defineResource({
        name: 'user',
        endpoint: 'users',
        idAttribute: 'id',
        searchFields: { // Lunr searchable fields and their respective boost
          name: 7,
          title: 3
        }
      });
      return resource;
    })
    .controller(function(User) {
      // first we fetch all the records
      User.findAll({limit: 1000}).then(function() {
        var users;
        // now we can search local records
        return users = User.search('tim');
      });
    });
    

    SearchableDS:

    angular.module("app")
    .constant('Lunr', lunr) // lunr.js
    .constant('_', _) // underscore.js
    .service('SearchableDS', function(DS, Lunr, _) {
      _(this).extend(DS); // extending DS with new capabilites
      this.defineResource = function(options) {
        var addToIndex, defaultOpts, index, resource;
        defaultOpts = {
          searchMapper: angular.identity, // optional. a function to create objects for a different lunr mapping. useful for e.g. when the records have nested objects
          searchFields: {}
        };
        options = _(defaultOpts).extend(options);
        resource = DS.defineResource(options);
        index = Lunr(function() { // create lunr index
          var _this = this;
          this.ref(options.idAttribute); 
          // add searchable fields and their boost value to the index
          _(options.searchFields).each(function(boost, name) {
            _this.field(name, {boost: boost})
          });
        });
        addToIndex = function(entity) {
          index.add(options.searchMapper(entity));
        };
        // wrap the original record-fetching methods so that they'll add newly fetched records to Lunr's index
        resource.findAll = (function() { 
          var originalFunc;
          originalFunc = resource.findAll;
          return function() {
            return originalFunc.apply(resource, arguments).then(function(entities) {
              return _(entities).each(addToIndex); // add to lunr index
            });
          };
        })();
        resource.find = (function() {
          var originalFunc;
          originalFunc = resource.find;
          return function() {
            return originalFunc.apply(resource, arguments).then(function(entity) {
              return addToIndex(entity);  // add to lunr index
            });
          };
        })();
        // full text search of local records using Lunr
        resource.search = function(str) {
          var entities, ids;
          ids = _(index.search(str)).pluck('ref'); // use Lunr only to find the record IDs
          entities = _(resource.getAll())
          .chain()
          .filter(function(t) {
            return ~ids.indexOf(t.id)
          }).sortBy(function(t) {
            return ids.indexOf(t.id)
          })
          .value();
          console.log(options.name + "#search: " + entities.length + " results for '" + str + "'");
          return entities;
        };
        return resource;
      };
      return this;
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-14
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-09
      • 2012-03-03
      相关资源
      最近更新 更多