Поиск в двух свойствах, используя один поисковый запрос
У меня есть объекты JSON, которые выглядят так:
[
{
"name": { "first": "John", "last": "Doe" }
},
{
"name": { "first": "Foo", "last": "Bar" }
}
]
Моя опция поиска FuseJS:
var searchOpts = {
shouldSort: true,
threshold: 0.2,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 5,
matchAllTokens: true,
keys: [{
name: "name.first",
weight: 0.3
}, {
name: "name.last",
weight: 0.3
}]
}
То, что я делаю, это выбор значения, введенного пользователем, и поиск по объекту, содержащему имена всех людей.
var fuse = new Fuse( peopleObj, searchOpts);
var result = fuse.search( query );
Все работает нормально, пока пользователь ищет только имя или фамилию, но если они, например, типа "Джон Доу", объект, который должен быть возвращен, не возвращается, но работает, если он только набирает "Джон" "или" Доу ".
Я могу добиться этого, просто установив другое свойство внутри объектов, таких как "name": {"fullName": "John Doe"}
но мне это неудобно, поскольку в будущем объем данных может увеличиться, а это будет просто пустой тратой вычислительной мощности.
Как мне убедиться, что FuseJS ищет name.first
а также name.last
имущество, объединяя их, а не отдельно. я думал matchAllTokens
1 ответ
К сожалению, fusejs не обеспечивает поиск по нескольким ключам на данный момент.
Вы можете следовать подходу, чтобы объединить все ключи, представляющие интерес, в один ключ, как
function combineAllKeyValues( obj, separator )
{
separator = separator || " ";
obj.all = Object.keys(obj.name).map(s=> obj.name[s]).join( separator );
return obj;
}
демонстрация
var peopleObj = [{
"name": {
"first": "John",
"last": "Doe"
}
},
{
"name": {
"first": "Foo",
"last": "Bar"
}
}
];
var searchOpts = {
shouldSort: true,
threshold: 0.2,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 5,
matchAllTokens: false,
keys: [{
name: "name.first",
weight: 0.3
}, {
name: "name.last",
weight: 0.3
}, {
name: "all",
weight: 0.1
}]
};
function combineAllKeyValues( obj, separator )
{
separator = separator || " ";
obj.all = Object.keys(obj.name).map(s=> obj.name[s]).join( separator );
return obj;
}
peopleObj = peopleObj.map( s => combineAllKeyValues(s) );
var fuse = new Fuse( peopleObj, searchOpts);
var result = fuse.search( "John Doe" );
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.0.4/fuse.min.js"></script>