Accessing results from collect() using neo4j-php-client - php

The below displays:
Marlena has 12 paintings (which is basically from the docs)
How do I access the data in collect(Paintings)
ex: title
$query = "MATCH (n:Artist)-[:PAINTED]->(Painting) RETURN n.first_name, collect(Painting) as paintings";
$result = $client->run($query);
foreach ($result->getRecords() as $record) {
echo sprintf('%s has %d paintings', $record->value('n.first_name'), count($record->value('paintings')));
echo '<br/>';
}
I would like to display:
Artist Name:
painting title
painting title
etc
I assume this data can be pull from either Painting or paintings. I am just unsure how to put together the query. It will display using print_r and the record so I know the data is coming through.

This should work for you:
$query = "MATCH (n:Artist)-[:PAINTED]->(Painting) RETURN n.first_name, collect(Painting) as paintings";
$result = $client->run($query);
foreach ($result->getRecords() as $record) {
echo sprintf('%s has %d paintings:<br/>', $record->value('n.first_name'), count($record->value('paintings')));
foreach ($record->value('n.paintings') as $painting) {
echo sprintf('- %s<br/>', $painting->value('title'));
}
echo '<br/>';
}

a) I suggest you alias your return values, it is easier to fetch them at the driver level
b) The paintings record value returns an array of Node objects, thus is iterable, no need to count for doing the for loop :
$query = "MATCH (n:Artist)-[:PAINTED]->(Painting) RETURN n.first_name as firstName, collect(Painting) as paintings";
$result = $client->run($query);
foreach($result->records() as $record) {
echo sprintf('%s painted %d paintings', $record->get('firstName'), count($record->get('paintings'))) . PHP_EOL;
foreach ($record->get('paintings') as $painting) {
echo sprintf('%s - %d views', $painting->value('title'), $painting->value('views')) . PHP_EOL;
}
}

I ended up getting it to work with the following:
foreach ($result->getRecords() as $record) {
$fname = $record->values()[0]->get('first_name');
$lname = $record->values()[0]->get('last_name');
echo '<strong>'.$fname.' '.$lname.' painted:</strong><br/>';
for ($x = 0; $x < count($record->values()[1]); $x++) {
print_r($record->values()[1][$x]->get('title'));
echo ' - ';
print_r($record->values()[1][$x]->get('views'));
echo ' views<br/>';
}
echo '<br/>';
}
Which provides the following output:
First Name Last Name painted:
Lumine - 86 views
Pooled Water - 69 views
Still Lake - 125 views
Final Notes
I actually tried code similar to what you suggested during my struggle to get this working. I'm a bit confused why it does not.
So I'm left wondering. Is what I come up with acceptable?

Related

how to use more than one variable in a group array?

I currently have the following code, it works great, but I've never tried to do anything more complex with this sort of thing. I'm wondering how I can add more variables to my result output.
$check_alt_sizes = mysqli_query($link, "SELECT model, version, size, category FROM items WHERE model = '$model' AND size != '$category' AND id != '$item_id'");
if (mysqli_num_rows($check_alt_sizes) >= 1) {
$group = array();
while ($row = mysqli_fetch_assoc($check_alt_sizes)) {
$group[ $row['category'] ][] = $row;
}
then later
foreach ($group as $sizes => $alt_size_urls) {
foreach ($alt_size_urls as $alt__size_url) {
echo "<a href='/items/"; echo "$alt_size_url[slug]"; // slug set elsewhere
echo "'>";
echo "$sizes</a>";
}
}
}
Now the $sizes part displays a list of sizes that I have gotten from grabbing $row['category'] in the initial $group from the query. What I would like to know is, how can I add more variables to this group, I've only ever dealt with doing it this way, never expanding it.
Currently it displays
Alternate Sizes:
size1
size2
but I would like to be able to add version as well, such as
Alternate Sizes:
Version1 - size1
Version2 - size1
Version3 - size2
I tried doing this:
echo $row['version']; echo "$sizes</a></p></li>";
But that just uses the first version found and applies it to every item. obviously because $sizes is looping and the version echo is not. How do I go about doing this?
I modified your source code with this one:
$group_size = "";
foreach ($group as $sizes => $alt_size_urls) {
$group_size .= "Alternate Sizes: <br>";
$ctr = 0;
foreach ($alt_size_urls as $alt__size_url) {
$group_size .= "<a href='/items/' " . $alt_size_url[slug] . (++$ctr) . "'>" . $sizes . "</a><br>";
}
}
echo $group_size;

PHP - Count how many results are displayed in foreach

With the foreach loop, I wanna count how many results are displayed. For example, if it's displaying
Jack Ane
Steve Jobs
Sara Bill
I want to echo that there are 3 results.
Likewise, if it's like
Marc Kil
Bill Smith
I want to echo that there are 2 results.
It's a bit tricky for me becasue this is my code:
<div>
<?php
$container = array();
if (is_array($row))
{
foreach ($row as $data) {
if(!isset($container[$data->first_name . $data->last_name])) {
$container[$data->first_name . $data->last_name] = $data;
echo $data->first_name . " " .$data->last_name . "</div>";
}
}
}
?>
</p>
</div>
How exactly would I be able to do that? Since these values are coming straight from the database, I was thinking of doing a database count but there are duplicate values in the database since I'm logging the views of users with the first and the last name. So when I try to do it, say for example there are 20 Jack Ane in my database. Then it shows me all of the 20 Jack Ane's instead of just one because I just want it once.
Sorry if it's confusing.
Thanks.
I traditional use the count() to do that if you dont use any :
foreach ($row as $data) {
if(!isset($container[$data->first_name . $data->last_name])) {
$container[$data->first_name . $data->last_name] = $data;
echo $data->first_name . " " .$data->last_name . "</div>";
}
}
echo "Results: " . count($row);
Hope that help you.
I suggest you to rewrite your query. If you will do this in right way, you will get faster solution, with no needs to new array and unnecessary "isset" checks.
The reason you get duplicated data from query may be:
1 - Wrong query logic
2 - Query is OK, but you need to use DISTINCT or GROUP BY to remove duplicates
If you use PDO, you can then get number of returned rows just by using rowCount() method
$sql="SELECT * from table WHERE blablabla";
$result = $this->db->query($sql);
$result->rowCount(); // here
Then you can fetch $result->fetchAll(); and print data.
You can to do a SELECT DISTINCT or a GROUP BY across the two columns to have the database do the work and eliminate the duplicate checking in your PHP. To do this you can use something like the following:
SELECT DISTINCT first_name, last_name FROM users;
SELECT first_name, last_name FROM users GROUP BY first_name, last_name;
DISTINCT is more succinct while GROUP BY supports more flexibility.
In your example, since you are building an associative array, you can just do a count() after the loop, but you will have cleaner code if you have the database do it:
$count = count($container);
You could do an easy variable that increments inside your foreach that gives you the exact count, then use the variable to create actions depending on it's value. Because if you count the container and you wish to filter out the results inside the container, you won't get the filtered amount.
<?php
$container = array();
if (is_array($row))
{
$count = 0;
foreach ($row as $data) {
if(!isset($container[$data->first_name . $data->last_name])) {
$container[$data->first_name . $data->last_name] = $data;
echo $data->first_name . " " .$data->last_name . "</div>";
$count++;
}
}
}
if ($count > 0) {
echo "There were $count results.";
}
?>
use:
echo "Results: " . count($container);

(PHP+MySQL) How can I echo the column name on a specific condition?

I am using PHP 5.4 with a MySQL database.
This database represents a media library. The table I'm dealing with has one column, "Title", with obvious contents, and then a series of boolean columns, representing the availability of that title on a given platform. So a row looks like
TITLE: "Curb Your Enthusiasm: The Game"
PS4: 0
Atari 2600: 1
Dreamcast: 0
And so on.
The PHP code I would like to write be, in pseudocode,
Echo row[0] (title)
Cycle through other cells in the row
If the cell is '0' or NULL, do nothing
But if the cell is '1', echo the name of that column
So the result would be the echoing of
Curb Your Enthusiasm: The Game (Atari 2600, WonderSwan, Saturn)
It's the fourth statement that I can't quite work out. It seems to require the function mysqli_fetch_field, but I'm not sure of the syntax, and nothing I try after googling quite works.
I'd really appreciate any advice or examples someone could offer!
$database = mysqli_connect(SERVER,USERNAME,PASSWORD,'games');
$query = mysqli_query($database,"SELECT * FROM games` WHERE NAME LIKE '%ZELDA%'");
while ($row = mysqli_fetch_row($query)) {
echo $row[0]; // Echo title
for ($i=0;$i<sizeof($row);$i++) {
if ($row[$i] === '1') {
// ???????
}
}
}
Here is some rough untested code that should hopefully get you going.
while ($row = mysqli_fetch_assoc($query)) {
$columns = array(); // this will track the additional columns we need to display
foreach($row AS $column => $value) {
if($column == "title") {
echo $value; // this is the title, just spit it out
continue;
}
if($value == 1) {
// We have a column to display!
$columns[] = $column;
}
}
if(count($columns)) {
// We have one or more column names to display
echo " (" . implode(", ",$columns) . ")";
}
}
Some things to point out:
Using mysqli_fetch_assoc will allow you access to column names along with the values, which is useful here.
Keep track of the columns you want to display in an array first, this makes it easier at the end of each loop to format the output.
Sounds like you can do something like this:
// Simulates DB fetch
$titles = array(
array(
'TITLE'=>'Curb Your Enthusiasm: The Game',
'PS4'=>0,
'Atari 2600'=>1,
'Dreamcast'=>0
),
array(
'TITLE'=>'Curb Your Enthusiasm: The Book',
'PS4'=>1,
'Atari 2600'=>1,
'Dreamcast'=>0
)
);
foreach($titles as $title){
// get supported platforms
$supportedPlatforms = array();
foreach($title as $titleAttribute=>$titleValue){
if($titleAttribute != 'TITLE' && $titleValue == 1)
$supportedPlatforms[] = $titleAttribute;
}
echo $title['TITLE'] . ' (' . implode(', ', $supportedPlatforms) . ')' . "<br>";
}
Try running it here: http://phpfiddle.org/lite/code/pr6-fwt

Displaying values from mysqli with loop

I need to be able to display the course_desc on line 30, beside the course_name.
<?php
$result = $db->query("select distinct c.dbid, c.course_name, c.course_image, m.module_id, m.module_name, m.module_name_id, m.module_image, m.hasFiles, m.files from courses c join modules_to_courses mc on (c.dbid = mc.courses_id) join modules m on (mc.modules_id = m.module_id)");
$course_name = $db->query("SELECT distinct course_name, course_desc FROM courses");
while ($temp = $course_name->fetch_assoc()) {
$courses[] = $temp['course_name'];
}
$final = array();
// Retrieve results
while ($row = $result->fetch_assoc()) {
// Add to final array via counter if valid course is found
if (in_array($row['course_name'], $courses)) {
$final[$row['course_name']][] = $row;
}
}
// Display if final array is not empty
if (!empty($final)) {
// Loop through each potential course name
foreach ($courses as $name) {
// Output if the course has values within the final array
if (array_key_exists($name, $final)) {
echo '<div>'."\n";
echo ' '. $name . "\n";
echo '<!-- list of modules -->'."\n";
// Loop through internal values
foreach ($final[$name] as $value) {
$module_name = $value['module_name'];
echo ' '. $module_name ."\n";
}
echo ' </div>'."\n";
}
}
}
?>
You already having your course description in $final so you can access it using,
$final[$name]['course_desc']
I have created a paste based on your with changes. Also note that it's need to change your $final array.
distinct course_name, course_desc means you are trying to fetch the values regarding to distinct course_name and distinct course_desc together. You may wanna use group by instead. If I understood correctly, your statement will not bring you distinct course names and their related course desc. (if that is what you want)

Displaying multidimensional array in php

I have an array like this:
$tset = "MAIN_TEST_SET";
$gettc = "101";
$getbid = "b12";
$getresultsid = "4587879";
$users["$tset"] = array(
"testcase"=>"$gettc",
"buildid"=>"$getbid",
"resultsid"=>"$getresultsid"
);
Arrays in PHP is confusing me.
I want to display some like this:
MAIN_TEST_SET
101 b12 4587879
102 b13 4546464
103 b14 5545465
MAIN_TEST_SET3
201 n12 45454464
MAIN_TEST_SET4
302 k32 36545445
How to display this?
Thanks.
print_r($users)
That will print your array out recursively in an intuitive way. See the manual: http://us2.php.net/manual/en/function.print-r.php
If you want to print it in the specific way you formatted it above you're going to have to write a custom function that uses foreach looping syntax like this:
<?php
echo "<table>";
foreach($users as $testSetName=>$arrayOfTestCases){
echo "<tr><td>".$testSetName."</td></tr>";
foreach($arrayOfTestCases as $k=>$arrayOfTestCaseFields){
//$arrayOfTestCaseFields should be an array of test case data associated with $testSetName
$i = 0;
foreach($arrayOfTestCaseFields as $fieldName => $fieldValue){
//$fieldValue is a field of a testcase $arrayOfTestCaseFields
if($i == 0){
//inject a blank table cell at the beginning of each test case row.
echo "<tr><td> </td>";
$i++;
}
echo "<td>".$fieldValue."</td>";
}
echo "</tr>";
}
}
echo "</table>";
?>
Your data should be composed as follows:
$tset = "MAIN_TEST_SET";
$gettc = "101";
$getbid = "b12";
$getresultsid = "4587879";
$users[$tset] = array();
$users[$tset][] = array( "testcase"=>"$gettc",
"buildid"=>"$getbid",
"resultsid"=>"$getresultsid"
);
$users[$tset][] = ... and so forth ...
To fix the data structure you present (as Victor Nicollet mentions in his comment) you need something like this:
$users = array(); // Create an empty array for the users? (Maybe testsets is a better name?)
$testset = array(); // Create an empty array for the first testset
// Add the test details to the testset (array_push adds an item (an array containing the results in this case) to the end of the array)
array_push($testset, array("testcase"=>"101", "buildid"=>"b12", "resultsid" => "4587879"));
array_push($testset, array("testcase"=>"102", "buildid"=>"b13", "resultsid" => "4546464"));
// etc
// Add the testset array to the users array with a named key
$users['MAIN_TEST_SET'] = $testset;
// Repeat for the other testsets
$testset = array(); // Create an empty array for the second testset
// etc
Of course there are much more methods of creating your data structure, but this one seems/looks the most clear I can think of.
Use something like this to create a HTML table using the data structure described above.
echo "<table>\n";
foreach($users as $tsetname => $tset)
{
echo '<tr><td colspan="3">'.$tsetname.'</td></tr>\n';
foreach($tset as $test)
echo "<tr><td>".$test['testcase']."</td><td>".$test['buildid']."</td><td>".$test['resultsid']."</td></tr>\n";
}
echo "</table>\n";
The first foreach iterates over your test sets and the second one iterates over the tests in a test set.
For a short uncustomisable output, you can use:
print_r($users)
alternatively, you can use nested loops.
foreach($users as $key => $user) {
echo $key . "<br />"
echo $user["testcase"] . " " . $user["buildid"] . " " . $user["resultsid"];
}
If you are not outputting to html, replace the <br /> with "\n"

Categories