bloodhound multiple dataset cause typeahead templa

2019-08-16 15:20发布

I've local elastic search server, install and running.

I instanciate 2 bloodhound object followig examples (can't post link because of reputation limitations)

If I use output as is, I have my results from my 2 datasource, no trouble.

When I want to use, remote: transform or filter option, to format the data, for using a custom template, I've trouble, the 2 template never get call.

Here's my code :

First bloodhound :

var nameSuggest = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
        queryTokenizer: Bloodhound.tokenizers.obj.whitespace,
        identify: 'nameSuggest',
        sufficient: 50,
        remote: {
            url: 'http://localhost:9200/test2/_suggest?pretty',
            prepare: function (query, settings) {
                settings.type = "POST";
                settings.contentType = "application/json; charset=UTF-8";
                search_payload = {
                    "suggest": {
                        "text": query,
                        "completion": {
                            "field": "suggest"
                        }
                    }

                };
                settings.data = JSON.stringify(search_payload);
                return settings;
            },
            transform: function(response) {
                return $.map(response.suggest[0].options, function (option) {
                    return {
                        optionText: option.text,
                        optionId:option.payload.id
                    };
                });

            }
        }
    });

Second dataset:

var mailSuggest = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
    queryTokenizer: Bloodhound.tokenizers.obj.whitespace,
    identify: 'mailSuggest',
    sufficient: 50,
    remote: {
        url: 'http://localhost:9200/test2/_suggest?pretty',
        prepare: function (query, settings) {
            settings.type = "POST";
            settings.contentType = "application/json; charset=UTF-8";
            search_payload = {
                "suggestMail": {
                    "text": query,
                    "completion": {
                        "field": "suggest2"
                    }
                }

            };
            settings.data = JSON.stringify(search_payload);
            return settings;
        },
        transform: function(response) {
            return $.map(response.suggestMail[0].options, function (option) {
                return {
                    optionText2: option.text,
                    optionId2:option.payload.id
                };
            });

        }
    }
});

And typeahead:

jQuery('#topSearch').typeahead({
            name:'topSearch',
            hint: true,
            highlight: true,
            limit: 20
        },
        {
            name: 'nameSuggest',
            display: 'data',
            source: nameSuggest,
            templates: {
                header: '<div><h3 class="">Noms</h3></div>',
                suggestion: function (data) {
                    console.log("Name");
                    return '<div>'+data.optionId+' - '+data.optionText+'</div>';
                }
            }
        },
        {
            name: 'mailSuggest',
            display: 'data',
            source: mailSuggest,
            templates: {
                header: '<div><h3 class="">Mails</h3></div>',
                suggestion: function (data) {
                    console.log("Mail");
                    return '<div>'+data.optionText2+'</div>';
                }
            }
        }
);

When I do :

console.log(nameSuggest);
console.log(mailSuggest);

I've two separate object, with unique names (the identify option) :

     Bloodhound { identify="nameSuggest",  sufficient=50,  local=[0],  plus...}

Bloodhound { identify="mailSuggest",  sufficient=50,  local=[0],  plus...}

but, in the remote part of each object I can see the transform and prepare section with the two object names (there are screenshot) :

first object

seconde object

If I remove transform option from both bloodhound instances, and templates for typeahead, it works, and I'v suggestions.

If I remove transform of the second bloodhound instance and template associated, first results are displayed, withing the template, and second result are displayed raw, but it works.

If I let the second template in typeahead init, without bloodhound associated transform, the second template header is displayed, but the data undefined (normal behavior I suppose).

So, somehow, transform of the second bloodhound break something, but I can't figure out what, and how.

Do I miss something, or did something wrong ?

1条回答
The star\"
2楼-- · 2019-08-16 15:29

Solved:

I have to add the size option to the query, to tell elastic to send more result:

var mailSuggest = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace,
    queryTokenizer: Bloodhound.tokenizers.obj.whitespace,
    identify: 'mailSuggest',
    sufficient: 50,
    remote: {
        url: 'http://localhost:9200/test2/_suggest?pretty',
        prepare: function (query, settings) {
            settings.type = "POST";
            settings.contentType = "application/json; charset=UTF-8";
            search_payload = {
                "suggestMail": {
                    "text": query,
                    "completion": {
                        "field": "suggest2",
                        "size": 20
                    }
                }

            };
            settings.data = JSON.stringify(search_payload);
            return settings;
        },
        transform: function(response) {
            return $.map(response.suggestMail[0].options, function (option) {
                return {
                    optionText2: option.text,
                    optionId2:option.payload.id
                };
            });

        }
    }
});

I tried with 20 for testing prupose.

查看更多
登录 后发表回答