使用一个搜索查询在两个属性中搜索

时间:2017-11-22 14:11:14

标签: javascript fuse.js

我有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 );

只要用户仅使用名字或姓氏进行搜索,一切正常,但如果他们为例如“John Doe”类型,则不会返回应该返回的对象,但只有它们才有效输入“John”或“Doe”。

我可以通过简单地设置像"name": {"fullName": "John Doe"}这样的对象中的另一个属性来实现这一点,但我对此不满意,因为将来数据可能会变大,这只会浪费处理能力。

如何确保FuseJS通过组合它们而非单独搜索name.firstname.last属性。我想matchAllTokens

1 个答案:

答案 0 :(得分:1)

不幸的是, fusejs 目前还没有提供跨多个密钥的搜索。

您可以按照这种方法将所有感兴趣的键组合成一个键,如

function combineAllKeyValues( obj, separator )
{
    separator = separator || " ";
    obj.all = Object.keys(obj.name).map(s=> obj.name[s]).join( separator );
    return obj;
}

<强>演示

&#13;
&#13;
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);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.0.4/fuse.min.js"></script>
&#13;
&#13;
&#13;