在没有服务器端代码的基础上进行搜索

时间:2022-05-02 15:46:30

I am trying to get all the users having the name that contains a given string from Firebase. For example, if I have these users:

我正在尝试从Firebase中获取所有具有包含给定字符串的名称的用户。例如,如果我有这些用户:

Devid, Andy, Bob

I would like to get all the users having the name that contains a 'D' so I expect this as result:

我想让所有的用户都有包含“D”的名字,所以我希望结果是:

Devid, Andy

This is my Firebase's structure at the moment:

这是我现在的基地结构:

在没有服务器端代码的基础上进行搜索

Since Firebase is case sensitive I've created an attribute name_ that contains the lowercase name.

由于Firebase是区分大小写的,所以我创建了一个包含小写名称的属性name_。

Using startAt and endAt I can get all the users with the name starting with a defined string

使用startAt和endAt,我可以获得所有以定义字符串开头的用户名

ref.orderByChild("name_").startAt(text).endAt(text+"\uf8ff").on('value', ...);

But this gives me only the users having the name that starts with a given string, for example if text is 'D' I'll get:

但这只给了我以给定字符串开头的用户名,例如,如果文本是'D',我会得到:

Devid

1) At the moment my query means, "give me all the users having name_ that starts with a given string" is there a way to make it mean "give me all the users which name contains a given string"? EDIT: NO

1)目前,我的查询的意思是,“给我所有以给定字符串开头的name_用户”,是否有办法让它表示“给我所有的用户一个包含给定字符串的名字”?编辑:不

Firebase Queries don't have anything similar to full-text search operators. To accomplish those, you'll either have to integrate an external full-text search engine, or come up with a very elaborate custom indexing scheme. Firebase and indexing/search

Firebase查询与全文搜索操作符没有任何相似之处。要实现这些,您必须集成一个外部全文搜索引擎,或者设计一个非常复杂的自定义方案索引。重火力点和索引/搜索

2) At the moment I don't want to have server side code, what can be a good and efficient way to implement custom indexes?

2)目前我不想使用服务器端代码,有什么方法可以实现自定义索引?

Thanks

谢谢

2 个解决方案

#1


11  

Ok - there's no way to do exactly what you want with your current structure.

好吧,没有办法完全按照你现在的结构去做。

However this just popped into my head:

然而,我突然想到:

users:
  user_1234
    first_name: "Devid"
    components:
       "D": true
       "e": true
       "v": true
       "i": true
       "d": true
  user_5678
    first_name: "Andy"
    components:
       "A": true
       "n": true
       "d": true
       "y": true
  user_1010
    first_name: "Bob"
    components:
       "B": true
       "o": true
       "b": true

and here's some ObjC Code to make it happen (and it's tested!)

这里有一些ObjC代码来实现它(它已经测试过了!)

Firebase *ref = [myRootRef childByAppendingPath:@"users"];

FQuery *q1 = [ref queryOrderedByChild:@"components/b"];
FQuery *q2 = [q1 queryEqualToValue:@1];

[q2 observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {

    NSLog(@"%@", snapshot.value);

}];

This code returns Bob.

这段代码返回鲍勃。

To get all of the 'd' people, change the "components/b" to "components/d"

要获得所有的“d”人员,请将“component /b”更改为“components/d”

Edit:

编辑:

You can get really crazy and add more combinations to expand your search capability

你可以疯狂地添加更多的组合来扩展你的搜索能力

users:
  user_1234
    first_name: "Devid"
    components:
       "D": true
       "e": true
       "v": true
       "i": true
       "d": true
       "De": true
       "Dev": true
       "Devi": true
       "Devid": true
       "ev": true
       "evi": true
       "evid": true
       ... etc

It would pretty simple to code up a few lines of code to iterate over the name and write out the combinations.

编写几行代码来迭代名称并写出组合非常简单。

Obviously it would be way more efficient (if you have a limited data set) to just read all of the first names into snapshot, dump them into an array and (in ObjC) use an NSPredicate to pull out what you need.

显然,将所有的名字读入快照、将它们转储到数组中以及(在ObjC中)使用NSPredicate提取所需内容会更有效(如果您的数据集有限)。

#2


1  

oxyzen library in github does that given you do inserts and updates with some wrapped firebase

github中的oxyzen图书馆会给你做一些插入和更新,用一些包着的firebase。

for the indexing part basically the function:

索引部分的基本功能是:

  1. JSON stringifies a document.
  2. JSON stringifies文档。
  3. removes all the property names and JSON to eave only the data (regex).
  4. 删除所有属性名和JSON,只保留数据(regex)。
  5. removes all xml tags (therefore also html) and attributes (remember old guidance, "data should not be in xml attributes") to leave only the pure text if xml or html was present.
  6. 删除所有xml标记(因此也包括html)和属性(请记住旧的指南,“数据不应该是xml属性”),以便在存在xml或html时只保留纯文本。
  7. removes all special chars and substitute with space (regex)
  8. 删除所有特殊字符,并用空格替换(regex)
  9. substitutes all instances of multiple spaces with one space (regex)
  10. 用一个空间替换多个空间的所有实例(regex)
  11. splits to spaces and cycles:
  12. 分割到空间和周期:
  13. for each word adds refs to the document in some index structure in your db tha basically contains childs named with words with childs named with an escaped version of "ref/inthedatabase/dockey"
  14. 对于每个单词,在数据库的索引结构中添加refs到文档中,基本上包含了用“ref/inthedatabase/dockey”的转义版本命名的带有childs的单词命名的childs
  15. then inserts the document as a normal firebase application would do
  16. 然后将文档插入到普通的firebase应用程序中

in the oxyzen implementation, subsequent updates of the document ACTUALLY reads the index and updates it, removing the words that don't match anymore, and adding the new ones.

在oxyzen实现中,文档的后续更新实际上读取索引并更新它,删除不再匹配的单词,并添加新的单词。

subsequent searches of words can easily find documents in the words child. multiple words searches are implemented using hits

后续的单词搜索可以很容易地找到单词child中的文档。使用点击实现多个单词搜索

#1


11  

Ok - there's no way to do exactly what you want with your current structure.

好吧,没有办法完全按照你现在的结构去做。

However this just popped into my head:

然而,我突然想到:

users:
  user_1234
    first_name: "Devid"
    components:
       "D": true
       "e": true
       "v": true
       "i": true
       "d": true
  user_5678
    first_name: "Andy"
    components:
       "A": true
       "n": true
       "d": true
       "y": true
  user_1010
    first_name: "Bob"
    components:
       "B": true
       "o": true
       "b": true

and here's some ObjC Code to make it happen (and it's tested!)

这里有一些ObjC代码来实现它(它已经测试过了!)

Firebase *ref = [myRootRef childByAppendingPath:@"users"];

FQuery *q1 = [ref queryOrderedByChild:@"components/b"];
FQuery *q2 = [q1 queryEqualToValue:@1];

[q2 observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {

    NSLog(@"%@", snapshot.value);

}];

This code returns Bob.

这段代码返回鲍勃。

To get all of the 'd' people, change the "components/b" to "components/d"

要获得所有的“d”人员,请将“component /b”更改为“components/d”

Edit:

编辑:

You can get really crazy and add more combinations to expand your search capability

你可以疯狂地添加更多的组合来扩展你的搜索能力

users:
  user_1234
    first_name: "Devid"
    components:
       "D": true
       "e": true
       "v": true
       "i": true
       "d": true
       "De": true
       "Dev": true
       "Devi": true
       "Devid": true
       "ev": true
       "evi": true
       "evid": true
       ... etc

It would pretty simple to code up a few lines of code to iterate over the name and write out the combinations.

编写几行代码来迭代名称并写出组合非常简单。

Obviously it would be way more efficient (if you have a limited data set) to just read all of the first names into snapshot, dump them into an array and (in ObjC) use an NSPredicate to pull out what you need.

显然,将所有的名字读入快照、将它们转储到数组中以及(在ObjC中)使用NSPredicate提取所需内容会更有效(如果您的数据集有限)。

#2


1  

oxyzen library in github does that given you do inserts and updates with some wrapped firebase

github中的oxyzen图书馆会给你做一些插入和更新,用一些包着的firebase。

for the indexing part basically the function:

索引部分的基本功能是:

  1. JSON stringifies a document.
  2. JSON stringifies文档。
  3. removes all the property names and JSON to eave only the data (regex).
  4. 删除所有属性名和JSON,只保留数据(regex)。
  5. removes all xml tags (therefore also html) and attributes (remember old guidance, "data should not be in xml attributes") to leave only the pure text if xml or html was present.
  6. 删除所有xml标记(因此也包括html)和属性(请记住旧的指南,“数据不应该是xml属性”),以便在存在xml或html时只保留纯文本。
  7. removes all special chars and substitute with space (regex)
  8. 删除所有特殊字符,并用空格替换(regex)
  9. substitutes all instances of multiple spaces with one space (regex)
  10. 用一个空间替换多个空间的所有实例(regex)
  11. splits to spaces and cycles:
  12. 分割到空间和周期:
  13. for each word adds refs to the document in some index structure in your db tha basically contains childs named with words with childs named with an escaped version of "ref/inthedatabase/dockey"
  14. 对于每个单词,在数据库的索引结构中添加refs到文档中,基本上包含了用“ref/inthedatabase/dockey”的转义版本命名的带有childs的单词命名的childs
  15. then inserts the document as a normal firebase application would do
  16. 然后将文档插入到普通的firebase应用程序中

in the oxyzen implementation, subsequent updates of the document ACTUALLY reads the index and updates it, removing the words that don't match anymore, and adding the new ones.

在oxyzen实现中,文档的后续更新实际上读取索引并更新它,删除不再匹配的单词,并添加新的单词。

subsequent searches of words can easily find documents in the words child. multiple words searches are implemented using hits

后续的单词搜索可以很容易地找到单词child中的文档。使用点击实现多个单词搜索