Bloodhound 匹配不适用于特殊字符

Bloodhound matching not working with special characters

我正在使用 typeahead.js 和 Bloodhound 来使用本地来源搜索用户:

let users = [
  {name: 'John Doe (john.doe@email.org)', value: '3421'},
  {name: 'Jane Doe (test@email.org)', value: '8100'},
];

匹配显示键为name:

$('input').typeahead(
  {
    minLength: 1,
    highlight: true
  },
  {
    name: 'users',
    displayKey: 'name',
    source: new Bloodhound({
      datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
      queryTokenizer: Bloodhound.tokenizers.whitespace,
      local: users
    })
  }
);

按用户名搜索时确实匹配,例如"John" 或 "Jane"。但如果您通过电子邮件搜索,则不会,例如"john.doe"、"test" 或 "email.org".

但是,如果删除括号,例如'John Doe john.doe@email.org' 然后 "john.doe" 匹配。虽然不是 "email.org"。

其他特殊字符,如 <,例如'John Doe <john.doe@email.org>' 有同样的问题。

为什么特殊字符会破坏数据匹配,我可以做些什么来帮助它?

这是一个working pen.

我可以多一个属性:

let users = [
  {name: 'John Doe (john.doe@email.org)', value: '3421', match: 'John Doe john.doe@email.org'},
  {name: 'Jane Doe (test@email.org)', value: '8100', match: 'Jane Doe test@email.org'},
];

并通过新密钥匹配:

datumTokenizer: Bloodhound.tokenizers.obj.whitespace('match')

或者我可以有一个新的 属性 email 并有以下数据分词器:

datumTokenizer: u => Bloodhound.tokenizers.whitespace([u.name + ' ' + u.email])

但这远非理想。但是我怎样才能使 name 键匹配?

看来你需要使用自己的分词器,像这样。

const customTokenizer = (user) => {
  const tokens = user.name.split(/[\s()]+/);
  console.info('Tokenizer', user, '=>', tokens);
  return tokens;
};

let users = [{
    name: 'John Doe (john.doe@email.org)',
    value: '3421'
    // , email: 'john.doe@email.org'
  },
  {
    name: 'Jane Doe (test@email.org)',
    value: '8100'
    //, email: 'test@email.org'
  },
];

$('input').typeahead({
  minLength: 1,
  highlight: true
}, {
  name: 'users',
  displayKey: 'name',
  source: new Bloodhound({
    // datumTokenizer: u => Bloodhound.tokenizers.whitespace([u.name + ' ' + u.email]),
    datumTokenizer: customTokenizer,
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: users
  })
});
.tt-menu {
  background-color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script>

<div id="search">
  <input type="text" placeholder="Search user">
</div>

为您的 datumTokenizerqueryTokenizer 使用 nonword 分词器。