Meteor - autocomplete with “distinct” feature?

我是研究僧i 提交于 2019-12-25 08:53:37

问题


I have a collection Songs which contains data in the following format:

{artist:"Dream Theater", title: "Pull me under"}, {artist:"Dream Theater", title: "Finally free"}

I am using the package mizzao-autocomplete There are more than 5000 entries, so I definetely need server-side autocompletion. On server I published the collection:

Meteor.publish("autocompleteArtists", function(selector, options) {
  Autocomplete.publishCursor(Songs.find(selector, options), this);
  this.ready();
});

Client subscription looks like:

Template.home.helpers({
    settings: function() {
        return {
            position: "top",
            limit: 5,
            rules: [{
                collection: 'Songs',
                subscription: 'autocompleteArtists',
                field: "artist",
                template: Template.songItem
            }]
        };
    }
});

Should I have both collection and subscription in the settings() function?

Last part, the client template:

{{> inputAutocomplete settings=settings id="artistInput" type="text" placeholder="Artist" length="20"}}

My purpose is to look for an artist and when I select it, to subscribe to a simple server publish which returns all songs belonging to that artist. The thing is, if I have multiple entries with the same artist, of course, the list of results is showing the artist multiple times. I would need to to somehow a "distinct" publish which would return all artists, but there's no such a feature in Meteor. I found some things implementing the aggregation and distinct, but I don't see how to use Autocomplete publishCursor function... My temporary solution was to denormalize and add a Artists collection, but I should not do that.

Is there a simpler way?


回答1:


It appears you need both the subscription and the collection argument if you want to do the autocomplete on the server.

Unfortunately, as you've noticed, there's not really a good way to enforce uniqueness. You can play around with aggregation, but unless it returns a cursor, it doesn't look like that's what you want (and, e.g., Meteorhacks:aggregate does not).

One (simple?) way around this is to identify a single instance of every artist and flag it (autocomplete: true); then you can use the filter option to filter where autocomplete = true. This is really easy to do if people are manually entering songs:

Meteor.methods({
  insertSong: function(song, artist) { 
    var entry = {title: song, artist: artist, autocomplete: false};
    if (Songs.find({artist: artist}).count() === 0) { entry.autocomplete = true; }
    Songs.insert(entry);
  }
});

Your rules then just needs to include a filter object:

...
rules: [{
            collection: 'Songs',
            subscription: 'autocompleteArtists',
            field: "artist",
            template: Template.songItem,
            filter: {autocomplete: true}
        }]
...

You'll then need another pub / sub to actually display the songs from the artist in question:

// Server
Meteor.publish("songsByArtist", function(artist) { 
  return Songs.find({artist: artist});
});

// Client
Template.home.events({ // listen for selection and subscribe
  "autocompleteselect input": function(event, template, doc) {

   Meteor.subscribe("songsByArtist", doc.artist);
  }
});

// And you can iterate like so with a helper:
songsToDisplay: function() { 
  return Songs.find();
}

<!-- HTML -->
{{#each songsToDisplay}}
  {{> songAndArtist}}
{{/each}}

You can play around with it on this MeteorPad. Sorry I can't think of a better way.



来源:https://stackoverflow.com/questions/30027668/meteor-autocomplete-with-distinct-feature

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!