1

I have many Telegram Keyboards in my Firebase, and I Want to Have an Advance Dictionery Search for Childs of Keyboards, I Mean in Secend Level Deep, that the user entered,
Forexample user entered rock, I want to get each Keyboards contain rock at the begin or middle or at the end, in This Example I have 3 Keyboards: morning, rock and rocky.

const ref = db.ref('Keyboards/rock');  //keyboard 1
const ref = db.ref('Keyboards/morning');  //keyboard 2
const ref = db.ref('Keyboards/rocky');  //keyboard 3

How Can I get and console.log: rock and rocky when user typed rock?
My Problem 90% Solved By @rymdmaskin But Advance Dictionery Search Still is Open.
equalTo and startAt and endAt Not Work, I need Something like contain, Someone Said to use Elastic Search (https://firebase.googleblog.com/2014/01/queries-part-2-advanced-searches-with.html)

Structure: enter image description here

Rules:

{
  "rules": {
    ".read": true,
    ".write": true,
      "Keyboards" : {
             ".indexOn": "Keyboards"
         }
  }
}

Code:

const ref = db.ref('/');
  ref.child('/').orderByChild('Keyboards').equalTo('rock').on("value", function(snapshot) {
    console.log(snapshot.val());
    key = snapshot.forEach(function(data) {
        console.log(data.key);
    });
});
Saeed Heidarizarei
  • 8,406
  • 21
  • 60
  • 103
  • what do you mean by put those in a string ? what are you trying to achieve really ? do you mean concatenate the content of each child node inside some kind of global var ? – adz5A Oct 04 '17 at 00:14
  • Forexample I have a bank of books name, when a user typed `rock` in bot, The bot will send all the books including `rock` name, in this example i have rock and rocky and bot should send 2 message to user, rock and rocky have some chids: id, text, photo and ..... – Saeed Heidarizarei Oct 04 '17 at 08:30
  • 1
    Firebase Database queries cannot search deeply nested properties. See my explanation here: https://stackoverflow.com/questions/27207059/firebase-query-double-nested I also suspect that you're dealing with a categorization problem, for which your data structure is not usable. See my explanation here: http://stackoverflow.com/questions/40656589/firebase-query-if-child-of-child-contains-a-value – Frank van Puffelen Oct 19 '17 at 03:17

3 Answers3

4

If I got you right you would like to do something like this.

Structure:

- Keyboards
  - 0
    - name: "rocks"
    - children
      - 0: "id"
      - 1: "desc"
  - 1
    - name: "rocky"
    - children
      - 0: "id"
      - 1: "desc"

Rules:

{
  "rules": {
    ".read": true,
    ".write": true,
      "Keyboards" : {
        "$key": {
           ".indexOn": "name"
        }
      }
  }
}

Code:

const ref = db.ref('/');
  ref.child('Keyboards').orderByChild('name').equalTo('rocks').on("value", function(snapshot) {
    console.log(snapshot.val());
    key = snapshot.forEach(function(data) {
        console.log(data.key);
    });
});

Is this what you are looking for?

Orlandster
  • 4,706
  • 2
  • 30
  • 45
  • is your Structure same as my Structure? – Saeed Heidarizarei Oct 16 '17 at 21:57
  • I've renamed `childs` to `children ` – Orlandster Oct 16 '17 at 21:59
  • I'm getting null in my terminal – Saeed Heidarizarei Oct 16 '17 at 22:02
  • I Don't want to update my data, my data is some books and i want to search and send to users, i will update my code now, – Saeed Heidarizarei Oct 16 '17 at 22:07
  • 2
    This will not work. The problem is your data structure. So if you want to make the code work you need of course to update your data. – Orlandster Oct 16 '17 at 22:09
  • 1
    Yeah sorry, not sure what you want to achieve either. And as @Orlandster says, I think it is better to restructure your data. Take a look at: https://firebase.google.com/docs/database/web/structure-data Im not sure but you might be able to grab the values by: `orderByKey().startAt("rock")` with your previous code. Also, the `indexOn` is just a warning, it is not an error, you could ignore it. – rymdmaskin Oct 17 '17 at 16:51
2

My suggestion was either change the structure on the database or use this query which seems to have solved the problem:

.orderByKey().startAt("rock")

I'm not so sure it will work for all your future cases tho because I think the query will start at rock but not end at rocky if you have more keyboards after rocky. I am just basing this on this source: Common SQL Queries converted for the Firebase Database

enter image description here

Saeed Heidarizarei
  • 8,406
  • 21
  • 60
  • 103
rymdmaskin
  • 508
  • 5
  • 13
0

Google's current method to do full text search seems to be syncing with either Algolia or BigQuery with Cloud Functions for Firebase.

Usage (elastic Search): (https://medium.com/joolsoftware/extending-firebase-with-cloud-functions-elasticsearch-129fbbb951e0)

Saeed Heidarizarei
  • 8,406
  • 21
  • 60
  • 103