Skip to content
This repository has been archived by the owner on Jun 2, 2024. It is now read-only.

Query on nested Arrays #33

Open
klopez0017 opened this issue Nov 11, 2018 · 4 comments
Open

Query on nested Arrays #33

klopez0017 opened this issue Nov 11, 2018 · 4 comments

Comments

@klopez0017
Copy link

Hi, I have this saved database with me in this format. As you can see accounts have multiple array elements containing accID, server, expiry, editable, payment, etc..
Whenever I try to use query it gives me no results. Is nested multi array supported at the moment?

$query5 = $db_List->query()->where('accounts.accID', '=', '123')->results();
echo var_dump($query5);
{
    "__created_at": 1541705828,
    "__updated_at": 1541706169,
    "data": {
        "accounts": [
            {
                "accID": "123",
                "server": "TEST",
                "expiry": 100,
                "editable": 200,
                "payment": "x",
                "parent_payment": "y",
                "notes": "z"
            },
            {
                "accID": "456",
                "server": "TEST",
                "expiry": 100,
                "editable": 200,
                "payment": "-",
                "parent_payment": "-",
                "notes": "Coco"
            }
        ],
        "username": "TEST",
        "password": "HASH",
        "email": "test@telus.com",
        "blocked": false
    }
}
@timothymarois
Copy link
Member

Hi @klopez0017

They should be designed that way as the docs state the examples of:

// You can also use `.` dot delimiter to use on nested keys
$users = $db->query()->where('status.language.english','=','blocked')->results();

What is the response you are receiving? I will take a look at this when I get in.

@timothymarois timothymarois added the Unexpected Results When the results are not what you expected. label Nov 11, 2018
@klopez0017
Copy link
Author

klopez0017 commented Nov 12, 2018

Hi @timothymarois,

Im getting an empty array.

My suspicion is that it doesnt properly read the iteration of the nested array. For example, to be able to read the first item I provided above, I should use

accounts[0]['accID'] and will return '123'

But if i use only the query,

accounts.accID is considered as accounts['accID']

Maybe if we can use something like a wild card in between?

Example:
....query->where("accounts.*.accID", "=", "123")->results();

@timothymarois
Copy link
Member

@klopez0017 I do see what you mean now. Its because it's in an array which doesn't know which to choose from since there is multiple. But still, that is a good point and should be addressed. I do like the functionality of setting accounts.accID = 123 It should intelligently find the correct array.

One thing to note about querying, at least in current form. It was designed to return the entire document as a whole, using queries to find documents instead of partial data. There are Custom Filters which not sure if it is something you could use in this case, or we could modify that if it gets your results.

@timothymarois timothymarois removed the Unexpected Results When the results are not what you expected. label Nov 12, 2018
@klopez0017
Copy link
Author

klopez0017 commented Nov 13, 2018

@timothymarois I will have a look on custom filters thank you. I'll try as well to help fix it and make a pull request to check if the Queried item is multi-nested array inside.

Below is a partially working code for a multi-nested array. It now successfully returns the first arrays.

    /**
    * field
    *
    * Gets property based on a string
    *
    * You can also use string separated by dots for nested arrays
    * key_1.key_2.key_3 etc
    *
    * @param string $field
    * @return string $context property
    */
    public function field($field)
    {
        $parts   = explode('.', $field);
        $context = $this->data;

        if ($field=='data')
        {
            return $context;
        }

        foreach($parts as $part)
        {
            if (trim($part) == '')
            {
                return false;
            }

            if (is_object($context))
            {
                if(!property_exists($context, $part))
                {
                    return false;
                }

                $context = $context->{$part};
            }
            else if (is_array($context))
            {                
                if(!array_key_exists($part, $context))
                {
                    /** A little modification with the code due to its an array inside */
                    if (is_array($context)) {
                        foreach($context as $item){
                            
                            if(!array_key_exists($part, $item))
                            {
                                return false;
                            }
                            return $item[$part];
                        }
                    }
                    return false;
                }
                
                $context = $context[$part];
            }
        }

        return $context;
    }

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants