powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / faceted search на sql
5 сообщений из 5, страница 1 из 1
faceted search на sql
    #39349179
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попытался реализовать faceted search а-ля юлмарт/амазон на sql, но в силу криворукости не выходит статистика, т.е. как обычно панель слева, где показаны списки категорий и тегов. Справа от тега указывается количество позиций с данным тегом, которые добавятся если пользователь выберет данный тег.

Создал таблицы
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
CREATE TABLE "DOCUMENT"
   (    "ID" NUMBER,
    "CREATE_DATE" DATE DEFAULT sysdate,
    "INTERNAL_NAME" VARCHAR2(255 BYTE)
   );




CREATE TABLE "TAG_DOCUMENT"
   (    "TAG" varchar2(255),
    "DOCUMENT_ID" NUMBER,
    tag_type_id number
   );


CREATE TABLE "TAG_TYPE"
   (  id number,
    description varchar2(255)
   );




Заполнил их данными

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
insert into TAG_TYPE (ID, DESCRIPTION)
values (3, 'HDD');

insert into TAG_TYPE (ID, DESCRIPTION)
values (2, 'Memory');

insert into TAG_TYPE (ID, DESCRIPTION)
values (1, 'Screen size');

Commit;


insert into DOCUMENT (ID, CREATE_DATE, INTERNAL_NAME)
values (5, to_date('08-11-2016', 'dd-mm-yyyy'), 'standalone pc');

insert into DOCUMENT (ID, CREATE_DATE, INTERNAL_NAME)
values (4, to_date('16-11-2016', 'dd-mm-yyyy'), 'mp3 player');

insert into DOCUMENT (ID, CREATE_DATE, INTERNAL_NAME)
values (3, to_date('08-11-2016', 'dd-mm-yyyy'), 'Notebook3');

insert into DOCUMENT (ID, CREATE_DATE, INTERNAL_NAME)
values (2, to_date('17-11-2016', 'dd-mm-yyyy'), 'notebook2');

insert into DOCUMENT (ID, CREATE_DATE, INTERNAL_NAME)
values (1, to_date('17-11-2016', 'dd-mm-yyyy'), 'notebook');

Commit;


insert into TAG_DOCUMENT (TAG, DOCUMENT_ID, TAG_TYPE_ID)
values ('2 Tb', 2, 3);

insert into TAG_DOCUMENT (TAG, DOCUMENT_ID, TAG_TYPE_ID)
values ('8 Tb', 5, 3);

insert into TAG_DOCUMENT (TAG, DOCUMENT_ID, TAG_TYPE_ID)
values ('4 Tb', 5, 3);

insert into TAG_DOCUMENT (TAG, DOCUMENT_ID, TAG_TYPE_ID)
values ('8 Tb', 3, 3);

insert into TAG_DOCUMENT (TAG, DOCUMENT_ID, TAG_TYPE_ID)
values ('6 Gb', 5, 2);

insert into TAG_DOCUMENT (TAG, DOCUMENT_ID, TAG_TYPE_ID)
values ('2 Gb', 2, 2);

insert into TAG_DOCUMENT (TAG, DOCUMENT_ID, TAG_TYPE_ID)
values ('1Gb', 1, 2);

insert into TAG_DOCUMENT (TAG, DOCUMENT_ID, TAG_TYPE_ID)
values ('14', 3, 1);

insert into TAG_DOCUMENT (TAG, DOCUMENT_ID, TAG_TYPE_ID)
values ('15', 2, 1);

insert into TAG_DOCUMENT (TAG, DOCUMENT_ID, TAG_TYPE_ID)
values ('17', 1, 1);

Commit;




Соответственно в поиске для типов тэгов должно быть И, а для значений тегов должно быть ИЛИ.

Запрос на поиск выглядит так
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
SELECT d.*,
       (
        select LISTAGG(' type id: ' || to_char(t.tag_type_id) || ' value: '|| t.tag , ', ') WITHIN GROUP (order by t.document_id)
        from tag_document t
        where t.document_id = d.id
       )tag_list_for_check
FROM document d
WHERE id IN (
             SELECT document_id
             FROM
                  (
                   SELECT tg.document_id,
                          COUNT(distinct tg.tag_type_id) over(partition BY tg.document_id) cnt_by_obj_tag_type_id,
                          prm.tag_type_id_count
                   FROM tag_document tg
                        LEFT JOIN
                                  (
                                   SELECT TAG_TYPE_ID,
                                          TAG,
                                          COUNT(distinct tag_type_id) over () tag_type_id_count
                                   FROM JSON_TABLE('
                                                    {
                                                      "tags" : [
                                                                {
                                                                 "tag_type_id" : "2",
                                                                 "values" : [
                                                                             {
                                                                              "value" : "6 Gb"
                                                                             },
                                                                             {
                                                                              "value" : "2 Gb"
                                                                             }
                                                                           ]
                                                               },
                                                               {
                                                                "tag_type_id" : "3",
                                                                "values" : [
                                                                            {
                                                                             "value" : "8 Tb"
                                                                            },
                                                                            {
                                                                             "value" : "4 Tb"
                                                                            },
                                                                            {
                                                                             "value" : "2 Tb"
                                                                            }
                                                                           ]
                                                               }
                                                             ]
                                                  }
                                                  ',
                                                   '$.tags[*]' NULL ON error COLUMNS (
                                                                                      tag_type_id number PATH '$.tag_type_id',
                                                                                      NESTED PATH '$.values[*]' COLUMNS (
                                                                                                                         tag VARCHAR2(200 CHAR) PATH '$.value'
                                                                                                                        )
                                                                                     )
                                               )
                                 ) prm ON tg.TAG_TYPE_ID = prm.TAG_TYPE_ID
                                       AND prm.tag          = tg.tag
                   where (prm.tag_type_id_count IS NOT NULL) or ('json provided' is null)
                  )
             WHERE cnt_by_obj_tag_type_id = nvl(tag_type_id_count, cnt_by_obj_tag_type_id)
    )




А вот со статистикой косяк именно из-за ИЛИ, при этом понять не могу как это сделать. Если не было бы категорий думаю бы заработало


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
SELECT d.*
FROM tag_document d
     left join (
                SELECT TAG_TYPE_ID,
                        TAG
                 FROM JSON_TABLE('
                                  {
                                    "tags" : [
                                              {
                                               "tag_type_id" : "2",
                                               "values" : [
                                                           {
                                                            "value" : "6 Gb"
                                                           },
                                                           {
                                                            "value" : "2 Gb"
                                                           }
                                                         ]
                                             },
                                             {
                                              "tag_type_id" : "3",
                                              "values" : [
                                                          {
                                                           "value" : "8 Tb"
                                                          },
                                                          {
                                                           "value" : "4 Tb"
                                                          },
                                                          {
                                                           "value" : "2 Tb"
                                                          }
                                                         ]
                                             }
                                           ]
                                }
                                ',
                                 '$.tags[*]' NULL ON error COLUMNS (
                                                                    tag_type_id number PATH '$.tag_type_id',
                                                                    NESTED PATH '$.values[*]' COLUMNS (
                                                                                                       tag VARCHAR2(200 CHAR) PATH '$.value'
                                                                                                      )
                                                                   )
                             )
               ) p on p.TAG_TYPE_ID = d.TAG_TYPE_ID
                   and p.tag = d.tag
WHERE
      p.tag is null
      and
      document_id in
                    (
                       SELECT document_id
                       FROM
                            (
                             SELECT tg.document_id,
                                    COUNT(distinct tg.tag_type_id) over(partition BY tg.document_id) cnt_by_obj_tag_type_id,
                                    prm.tag_type_id_count
                             FROM tag_document tg
                                  LEFT JOIN
                                            (
                                             SELECT TAG_TYPE_ID,
                                                    TAG,
                                                    COUNT(distinct tag_type_id) over () tag_type_id_count
                                             FROM JSON_TABLE('
                                                              {
                                                                "tags" : [
                                                                          {
                                                                           "tag_type_id" : "2",
                                                                           "values" : [
                                                                                       {
                                                                                        "value" : "6 Gb"
                                                                                       },
                                                                                       {
                                                                                        "value" : "2 Gb"
                                                                                       }
                                                                                     ]
                                                                         },
                                                                         {
                                                                          "tag_type_id" : "3",
                                                                          "values" : [
                                                                                      {
                                                                                       "value" : "8 Tb"
                                                                                      },
                                                                                      {
                                                                                       "value" : "4 Tb"
                                                                                      },
                                                                                      {
                                                                                       "value" : "2 Tb"
                                                                                      }
                                                                                     ]
                                                                         }
                                                                       ]
                                                            }
                                                            ',
                                                             '$.tags[*]' NULL ON error COLUMNS (
                                                                                                tag_type_id number PATH '$.tag_type_id',
                                                                                                NESTED PATH '$.values[*]' COLUMNS (
                                                                                                                                   tag VARCHAR2(200 CHAR) PATH '$.value'
                                                                                                                                  )
                                                                                               )
                                                         )
                                           ) prm ON tg.TAG_TYPE_ID = prm.TAG_TYPE_ID
                                                 AND prm.tag          = tg.tag
                             where (prm.tag_type_id_count IS NOT NULL) or ('json provided' is null)
                            )
                      )



Собственно, подскажите, может пару статей куда копать.
...
Рейтинг: 0 / 0
faceted search на sql
    #39349199
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот тут какие-то наброски sql нашёл, но мне кажется, что они требуют динамического sql, а без него как раз бы хотелось обойтись, ибо то, что выбрал юзер, мне присылают json-ном
...
Рейтинг: 0 / 0
faceted search на sql
    #39349202
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
точнее так
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
SELECT d.tag,
       d.tag_type_id,
       count(*)
FROM tag_document d
     left join (
                SELECT TAG_TYPE_ID,
                        TAG
                 FROM JSON_TABLE('
                                  {
                                    "tags" : [
                                              {
                                               "tag_type_id" : "2",
                                               "values" : [
                                                           {
                                                            "value" : "6 Gb"
                                                           },
                                                           {
                                                            "value" : "2 Gb"
                                                           }
                                                         ]
                                             },
                                             {
                                              "tag_type_id" : "3",
                                              "values" : [
                                                          {
                                                           "value" : "8 Tb"
                                                          },
                                                          {
                                                           "value" : "4 Tb"
                                                          },
                                                          {
                                                           "value" : "2 Tb"
                                                          }
                                                         ]
                                             }
                                           ]
                                }
                                ',
                                 '$.tags[*]' NULL ON error COLUMNS (
                                                                    tag_type_id number PATH '$.tag_type_id',
                                                                    NESTED PATH '$.values[*]' COLUMNS (
                                                                                                       tag VARCHAR2(200 CHAR) PATH '$.value'
                                                                                                      )
                                                                   )
                             )
               ) p on p.TAG_TYPE_ID = d.TAG_TYPE_ID
                   and p.tag = d.tag
WHERE
      p.tag is null
      and
      document_id in
                    (
                       SELECT document_id
                       FROM
                            (
                             SELECT tg.document_id,
                                    COUNT(distinct tg.tag_type_id) over(partition BY tg.document_id) cnt_by_obj_tag_type_id,
                                    prm.tag_type_id_count
                             FROM tag_document tg
                                  LEFT JOIN
                                            (
                                             SELECT TAG_TYPE_ID,
                                                    TAG,
                                                    COUNT(distinct tag_type_id) over () tag_type_id_count
                                             FROM JSON_TABLE('
                                                              {
                                                                "tags" : [
                                                                          {
                                                                           "tag_type_id" : "2",
                                                                           "values" : [
                                                                                       {
                                                                                        "value" : "6 Gb"
                                                                                       },
                                                                                       {
                                                                                        "value" : "2 Gb"
                                                                                       }
                                                                                     ]
                                                                         },
                                                                         {
                                                                          "tag_type_id" : "3",
                                                                          "values" : [
                                                                                      {
                                                                                       "value" : "8 Tb"
                                                                                      },
                                                                                      {
                                                                                       "value" : "4 Tb"
                                                                                      },
                                                                                      {
                                                                                       "value" : "2 Tb"
                                                                                      }
                                                                                     ]
                                                                         }
                                                                       ]
                                                            }
                                                            ',
                                                             '$.tags[*]' NULL ON error COLUMNS (
                                                                                                tag_type_id number PATH '$.tag_type_id',
                                                                                                NESTED PATH '$.values[*]' COLUMNS (
                                                                                                                                   tag VARCHAR2(200 CHAR) PATH '$.value'
                                                                                                                                  )
                                                                                               )
                                                         )
                                           ) prm ON tg.TAG_TYPE_ID = prm.TAG_TYPE_ID
                                                 AND prm.tag          = tg.tag
                             where (prm.tag_type_id_count IS NOT NULL) or ('json provided' is null)
                            )
                      )
group by d.tag,
         d.tag_type_id
...
Рейтинг: 0 / 0
faceted search на sql
    #39349227
Фотография Shtock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. из-за того, что в рамках одного tag_type_id может быть несколько значений похоже всё портится
...
Рейтинг: 0 / 0
faceted search на sql
    #39349254
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не осилил. Заведи блог - там можно безнаказанно струячить потоки сознания без вреда окружающим.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / faceted search на sql
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]