За последние 24 часа нас посетили 30475 программистов и 1808 роботов. Сейчас ищет 791 программист ...

Поиск в JSON (было: Сравнение масcивов)

Тема в разделе "MySQL", создана пользователем ghostcom, 2 апр 2019.

  1. ghostcom

    ghostcom Активный пользователь

    С нами с:
    17 фев 2016
    Сообщения:
    92
    Симпатии:
    2
    Ага, что об стенку горох.
     
  2. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    @ghostcom выложи рабочие массивы (var_export() а не print_r())
     
  3. ghostcom

    ghostcom Активный пользователь

    С нами с:
    17 фев 2016
    Сообщения:
    92
    Симпатии:
    2
    arr1
    Код (Text):
    1.  
    2. array (
    3.   'prop_2_size' =>
    4.   array (
    5.     'group' => 'size',
    6.     'grouptitle' => 'Size',
    7.     'value' => '4',
    8.   ),
    9.   'prop_2_color' =>
    10.   array (
    11.     'group' => 'color',
    12.     'grouptitle' => 'Цвет',
    13.     'value' => '7',
    14.   ),
    15. )
    arr2
    Код (Text):
    1.  
    2. array (
    3.   'dependent0' =>
    4.   array (
    5.     'id' => '1554009142201',
    6.     'sku' => 'R5-BNT5656-O-XXL',
    7.     'prop' =>
    8.     array (
    9.       'color' => '8',
    10.       'size' => '4',
    11.     ),
    12.     'img' => '',
    13.     'act' => '=',
    14.     'price' => '200',
    15.     'quantity' => '6',
    16.   ),
    17.   'dependent1' =>
    18.   array (
    19.     'id' => '1554009142202',
    20.     'sku' => 'R5-BNT5656-G-XXL',
    21.     'prop' =>
    22.     array (
    23.       'color' => '7',
    24.       'size' => '4',
    25.     ),
    26.     'img' => '',
    27.     'act' => '=',
    28.     'price' => '200',
    29.     'quantity' => '4',
    30.   ),
    31.   'dependent2' =>
    32.   array (
    33.     'id' => '1554009142203',
    34.     'sku' => 'R5-BNT5656-B-S',
    35.     'prop' =>
    36.     array (
    37.       'color' => '6',
    38.       'size' => '2',
    39.     ),
    40.     'img' => '',
    41.     'act' => '=',
    42.     'price' => '200',
    43.     'quantity' => '13',
    44.   ),
    45. )
    --- Добавлено ---
    ЗАДАЧА: Найти ID во втором массиве где color==7 && size==4
     
  4. ghostcom

    ghostcom Активный пользователь

    С нами с:
    17 фев 2016
    Сообщения:
    92
    Симпатии:
    2
    В общем сделал так. Можно вставить в песочницу http://phpfiddle.org/

    PHP:
    1. <?php
    2.  
    3. $array1 = array (
    4.     'prop_2_size' =>
    5.     array (
    6.         'group' => 'size',
    7.         'grouptitle' => 'Size',
    8.         'value' => '4',
    9.     ),
    10.     'prop_2_color' =>
    11.     array (
    12.         'group' => 'color',
    13.         'grouptitle' => 'Цвет',
    14.         'value' => '8',
    15.     ),
    16. );
    17.  
    18. $array2 = array (
    19.     'dependent0' =>
    20.     array (
    21.         'id' => '1554009142201',
    22.         'sku' => 'R5-BNT5656-O-XXL',
    23.         'prop' =>
    24.         array (
    25.             'color' => '8',
    26.             'size' => '4',
    27.         ),
    28.         'img' => '',
    29.         'act' => '=',
    30.         'price' => '200',
    31.         'quantity' => '6',
    32.     ),
    33.     'dependent1' =>
    34.     array (
    35.         'id' => '1554009142202',
    36.         'sku' => 'R5-BNT5656-G-XXL',
    37.         'prop' =>
    38.         array (
    39.             'color' => '7',
    40.             'size' => '4',
    41.         ),
    42.         'img' => '',
    43.         'act' => '=',
    44.         'price' => '200',
    45.         'quantity' => '4',
    46.     ),
    47.     'dependent2' =>
    48.     array (
    49.         'id' => '1554009142203',
    50.         'sku' => 'R5-BNT5656-B-S',
    51.         'prop' =>
    52.         array (
    53.             'color' => '6',
    54.             'size' => '2',
    55.         ),
    56.         'img' => '',
    57.         'act' => '=',
    58.         'price' => '200',
    59.         'quantity' => '13',
    60.     ),
    61. );
    62.  
    63. $b = array();
    64.  
    65. // преобразовал массив к виду $array2['dependentX']['prop']
    66. foreach($array1 as $key1 => $val1)
    67. {
    68.     if (strpos($key1, 'prop_2') === 0)
    69.     {
    70.         $a = array($val1['group'] => $val1['value']);
    71.         $b = array_merge( $a, $b);
    72.     }
    73. }
    74.  
    75. // перебрал $array2 и сравнил с $b
    76. foreach($array2 as $key2 => $val2)
    77. {
    78.     if (empty(array_diff_assoc($val2['prop'], $b)))
    79.     {
    80.         $id = $val2['id'];
    81.         break;
    82.     }
    83. }
    84.  
    85. echo 'id = ' . $id;
    86. ?>

    Всем спасибо!
     
  5. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    @ghostcom И вам спасибо за интересный вопрос )
    PHP:
    1. foreach($arr2 as $ar){
    2.   foreach ($ar as $k => $v){
    3.      if ($v === ['color'=>$arr1['prop_2_color']['value'],
    4.       'size'=>$arr1['prop_2_size']['value']]){
    5.          echo $ar['id'];
    6.      }
    7.   }
    8. }
     
  6. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    запрос по двум параметрам из бд по полю JSON вернувший 10тыс записей с копейками из миллиона, занял полторы секунды
    причём поле не индексировано
    хотел бы я посмотреть как ты выгрузишь миллион записей в РНР и что-то там будешь искать
     
  7. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Так можно отсортировать:
    Код (Text):
    1. DELIMITER //
    2. CREATE PROCEDURE proc()
    3. BEGIN
    4. SET @p := 0;
    5. WHILE @p<3 DO
    6. SET @id := CONCAT('$[', @p,'].id');
    7. SET @c := CONCAT('$[', @p,'].prop.color');
    8. SET @s := CONCAT('$[', @p,'].prop.size');
    9. SELECT JSON_EXTRACT(prop->'$.dependent.*',@id) id,
    10. JSON_EXTRACT(prop->'$.dependent.*',@c) color,
    11. JSON_EXTRACT(prop->'$.dependent.*',@s) size
    12. FROM `products`;
    13. SET @p:=@p+1;
    14. END WHILE;
    15. END //
    16. CALL proc()
     
  8. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @keren, необходимо найти значения, задача решается всего одним простым запросом.
     
  9. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Неужели? Тут и artoodetoo говорил что данные неудобны, так что не нужно из себя строить великого программиста.
     
  10. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    из разряда - Если нельзя, но очень хочется :)
    PHP:
    1. SELECT
    2.     JSON_UNQUOTE(JSON_EXTRACT(arr, CONCAT('$[', ind, '].id'))) id
    3. FROM ( SELECT prop->'$.dependent.*' AS arr FROM `products` WHERE id = 12 ) arrays
    4. JOIN ( /* этот кусок генерируешь сам, сколько надо, или джойнишь с вспомогательной таблицей */
    5.     SELECT 0 AS ind UNION
    6.     SELECT 1 AS ind UNION
    7.     SELECT 2 AS ind -- ...
    8. ) AS indexes
    9. WHERE 1
    10.     AND JSON_UNQUOTE(JSON_EXTRACT(arr, CONCAT('$[', ind, '].prop.size'))) = 4
    11.     AND JSON_UNQUOTE(JSON_EXTRACT(arr, CONCAT('$[', ind, '].prop.color'))) = 7
    12. ;
    а вообще, лучше вынести это из JSON. тогда будет простой и быстрый запрос поиска. а не этот франкенштейн.

    либо юзаем MYSQL8, там есть JSON_TABLE()
     
    ghostcom и keren нравится это.