is there a way in angularfire to query for matching AND condition

前端 未结 1 1343
眼角桃花
眼角桃花 2020-12-22 12:38

How we can query to firebase from angularfire to match two conditions. i wanted to search below two conditions as AND match

  1. if your key has color red
相关标签:
1条回答
  • 2020-12-22 13:20

    A Firebase query can currently only contain one orderBy... call. They can also only query properties that are one level below the nodes being returned.

    So you cannot implement your requirements in the way you probably initially hoped:

    // THIS IS AN EXAMPLE THAT WILL NOT WORK
    ref.child('color')
       .orderByChild('color').equalTo('red')
       .orderByChild('color/categories').equalTo('hex');
    

    Approach 1: add a new property that combines the properties you want to filter on

    In some cases, you can get away with introducing a top-level property that combines the values you want to filter on. So let's say your color can only be in one category. You could then add an additional colorcategory property:

    {
    
      "color" : {
        "-UqPNlZ8ddgdGMFSsD" : {
          "color" : "red",
          "colorcategory": "redhex",
          "categories" : {
            "hex" : {
              "subcategory" : [ "#111", "#333" ]
            }
          },
          "status" : "ok"
        },
        "-U9P4pBpYiId3ID64K" : {
          "color" : "blue",
          "colorcategory" : "bluehex",
          "categories" : {
            "hex" : {
              "subcategory" : [ "#ffffd", "#eee" ]
            }
          },
          "status" : "ok"
        },
        "-U9UgOdffZdfdbSydF" : {
          "color" : "green",
          "colorcategory" : "greenhex",
          "categories" : {
            "hex" : {
              "subcategory" : [ "#333", "#555" ]
            }
          },
          "status" : "ok"
        }
    }
    

    And filter on that:

    ref.child('color')
       .orderByChild('colorcategory').equalTo('redhex')
    

    This will work when you have two single-value properties, even when they're on different levels in the JSON structure, since you're normalizing those properties and level into a single value on the right level.

    But since your categories are multi-value, this approach also won't work. The only approach that I can think of is that you create a so-called secondary index on your data.

    Approach 2: create a secondary index on the properties that you want to filter on

    An index in a NoSQL database is a data structure, much like a multi-column index in a relational database, that just exists for your queries. In this case, since you want to query on the combination of color and category, I'd expect an index color_category or maybe even color_category_subcategory.

    color_category_subcategory:
      "red_hex_111": "-UqPNlZ8ddgdGMFSsD"
      "red_hex_333": "-UqPNlZ8ddgdGMFSsD"
      "blue_hex_ffffd": "-U9P4pBpYiId3ID64K"
      "blue_hex_eee": "-U9P4pBpYiId3ID64K"
      "green_hex_333": "-U9UgOdffZdfdbSydF"
      "green_hex_555": "-U9UgOdffZdfdbSydF"
    

    You will have to create and maintain this index from your own code , either in the client-side application or by running a server-side process that creates it. But once you have the index in place, you can query it:

    ref.child('color_category_subcategory')
       .orderByKey().equalTo('red_hex_333')
       .on('value', function(snapshot) {...
    

    Or by range:

    ref.child('color_category_subcategory')
       .orderByKey().startAt('blue_hex').endAt('blue_hex~')
       .on('value', function(snapshot) {...
    

    The ~ above is not a special operator, but just a character that happens to fall after all other characters in an ASCII sequence. So filtering ['blue_hex', 'blue_hex~'] will give all blue hexes.

    0 讨论(0)
提交回复
热议问题