首页 > 解决方案 > Firestore - 简单的全文搜索解决方案

问题描述

我知道 Firestore 不支持全文搜索,它为我们提供了使用第三方服务的解决方案。然而,我找到了一个简单的“全文搜索”的简单解决方案我认为这可能会帮助那些不想像我一样使用第三方服务来完成如此简单任务的人。我正在尝试搜索保存在我的 companyName 下的 firestore 集合中的公司名称,它可以是任何格式,例如“My Awesome Company”。使用 companyName 添加新公司或更新 companyName 中的值时,我还保存了 searchName ,它与公司名称的值相同,但小写没有空格

searchName: removeSpace(companyName).toLowerCase() 

removeSpace 是我的简单自定义函数,它从文本中删除所有空格

export const removeSpace = (string) => {
    return string.replace(/\s/g, '');
}

这会将我们的公司名称转换为保存在 searchName 中的myawesomecompany

现在我有一个firestore函数来搜索通过searchName索引并返回companyName的公司。最小搜索值是没有最后一个字符的搜索值,最大搜索值是添加了“zzzzzzzzzzzzzzzzzzzzzzzz”转换为小写的搜索值。这意味着如果您搜索My Aw,则最小值将为mya,最大值将为myawzzzzzzzzzzzzzzzzzzzzzzz

exports.handler = ((data) => {
const searchValue = data.value.replace(/\s/g, '').toLowerCase()
const minName = searchValue.substr(0, searchName.length-1)
const maxName = searchValue + "zzzzzzzzzzzzzzzzzzzzzzzz"
let list = []
const newRef = db.collection("user").where("profile.searchName", ">=", minName).where("profile.searchName", "<=", maxName)
return newRef.get()
.then(querySnapshot => {
    querySnapshot.forEach(doc => {
        list.push({ name: doc.data().profile.companyName})
    })
    return list
})
})

我没有时间完全测试它,但到目前为止它没有任何问题。如果您发现它有任何问题,请告诉我。现在的问题是

“z”字符是firestore中的最高值字符,还是有其他更体面的方法可以在不添加“zzzzzzzzzzzzz”的情况下添加到搜索值最大值中?

标签: reactjsgoogle-cloud-firestoregoogle-cloud-functions

解决方案


我喜欢您对文本进行预处理以便对其进行查询的决定,但是您可以通过将小写关键字与用户一起存储并搜索这些关键字来提供更灵活的搜索。换句话说,变换:

"My Awesome Company"

至...

{ my: true, awesome: true, company: true }

...并对此进行测试。

添加/更新属性时:

// save keywords on the user
let keywords = {}
companyName.split(' ').forEach(word => keywords[word.toLowerCase()] = true)

查询时:

let searchKeywords = userInputString.split(' ').map(word => word.toLowerCase())

let collection = db.collection("user")
searchKeywords.forEach(keyword => { 
  collection = collection.where(`keywords.${keyword}` , '==' , true);
}); 

推荐阅读