Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Denormalize Firebase Data For Tag Search

I have the following data structure and would like to return the "products" associated with a tag. is it possible to achieve this with the current data structure? If not, how should I structure the data, and what would the query look like to return all "products" that have "Tag 2" for example?

{
  "accounts" : {
    "-KRPU3FyKT4oPWHYjDrr" : {
      "userId" : "1"
    },
    "-kjnsvakljsndfme;lnmv" : {
      "userId" : "2"
    }
},

  "products" : {
    "-KXcnfob3Vo3s8bL9WSI" : {
      "name" : "Product 1",
      "description" : "Description of product 1",
      "tags" : [ "Tag 1", "Tag 2", "Tag 3", "etc." ],
      "url" : "websiteURL1.com",

    },
    "-KXcnfob3Vo3s8bL9WSI" : {
      "name" : "Product 2",
      "description" : "Description of product 2",
      "tags" : [ "Tag 1", "Tag 2", "Tag 3", "etc." ],
      "url" : "websiteURL2.com",

    }
  }
}

My last attempt was this:

firebase.database().ref.child('products').orderByChild('tags').equalTo("Tag 1").once('value', function(products)

Obviously no success.. This however does return all "products" with a tag:

firebase.database().ref.child('products').orderByChild('tags').once('value', function(products)

Thanks in advance!

like image 407
MacD Avatar asked Jan 05 '23 23:01

MacD


1 Answers

If you restructure your data like this:

"products" : {
  "-KXcnfob3Vo3s8bL9WSI" : {
    "name" : "Product 1",
    "description" : "Description of product 1",
    "tags" : {
      "Tag1": true,
      "Tag2": true
    },
    "url" : "websiteURL1.com"
  },
  "-KXcnfob3Vo3s8bL9WSI" : {
    "name" : "Product 2",
    "description" : "Description of product 2",
    "tags" : {
      "Tag3": true,
      "Tag4": true
    },
    "url" : "websiteURL2.com"
  }
}

You can use a deep-path query to obtain the products that have a particular tag:

firebase.database()
  .ref('products')
  .orderByChild('tags/Tag1')
  .equalTo(true)
  .once('value', function (products) {
    console.log(products.val());
  });

Note that this approach will work only if you have a fixed number of known tags, as an index will be required for each tag.

like image 128
cartant Avatar answered Jan 07 '23 19:01

cartant