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>
为您的 datumTokenizer
和 queryTokenizer
使用 nonword
分词器。
我正在使用 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>
为您的 datumTokenizer
和 queryTokenizer
使用 nonword
分词器。