Показать сообщение отдельно
Старый 26.10.2015, 09:51   #23
St_AnGer
Элита
 
Аватар для St_AnGer
 
Регистрация: 21.01.2010
Адрес: Россия, Рязанская область, г.Михайлов
Сообщений: 2,067
Написано 1,185 полезных сообщений
(для 2,828 пользователей)
Ответ: Чат: PHP + MySQLi или что то другое?

И тут неожиданно возникла странность. Нужно сделать удаление пользователей из списка, и казалось бы всё просто, но...

В общем, опишу сначала добавление друзей в список контактов. Происходит оно у меня так:
ищем друга через поиск, жмакаем кнопку "добавить", обращаемся к соответствующему API где происходит добавление друга в массив friends текущего пользователя. В базе о друзьях хранятся следующие поля:
1) _id - _id существующего в базе пользователя, который является друга
2) group_id - _id группы которую создали мы (группы - что то типа групп из Аськи, просто группировка контактов как удобнее, что бы можно было писать сразу всей группе, не создавая комнату и не добавляя туда всех вручную)
3) state - состояние друга в списке (0 - удалён, 1 - в списке)
4) add_date - дата добавления

Добавление происходит двумя путями:
1) добавляемого друга нету и никогда не было в списке - всё просто, делаем Push в массив friends с нужными полямиь, state, соответственно, равен 1;
2) друг уже когда то был в спиcке друзей, но мы его удалили и сейчас в массиве friends у него state равняется 0 - тут в целом тоже просто, хотя пришлось поразвлекаться в итоге свёл всё к одному "запросу" в базу:
collection.update({_id:owner}, {$push:{friends:{_id:friend, group_id:1,state:1,add_date:addDate}}});
group_id = 1 это общая группа с названием "Без группы".

Так вот, этот этап я прекрасно пережил, всё шикарно и жизнь вроде бы удалась, удаление пользователя из списка друзей не должно стать какой то проблемой, но... Есть одно требование, которое надо было выполнить, что я и сделал. Заключается оно в том, что один друг может у текущего пользователя числиться сразу в нескольких группах. Это я реализовал тоже довольно просто - ещё один push в массив friends, с group_id нужной группы, всё работает. Соответственно с этого момента появляется 2 пути удаления:
1) полное удаление из списка (легко и не принуждённо ставим state = 0 всем текущим записям с _id друга в массиве friends пользователя)
2) удаление из какой то определённой группы (вот тут то и возникла проблема)

Контактный список выглядит сейчас вот так:
Нажмите на изображение для увеличения
Название: trouble_with_chat.PNG
Просмотров: 953
Размер:	19.4 Кб
ID:	22003

Проблема с удалением заключается в том, что когда я нажимаю удалить выделенного пользователя (Алексея) - у меня удаляется (state = 0) ПЕРВЫЙ пользователь в этой группе (то есть удаляется Людмила, а не Алексей).

Запрос на удаление вот такой:

collection.update({_id:owner,"friends._id":friend,"friends.group_id":group_id}, {$set:{"friends.$.state":0}})
Такое поведение начинается если указывать _id группы из которой удаляем ("friends.group_id":group_id) в выборке на update. Если _id группы не указать - удаляется именно Алексей, но из первой группы (что вполне логично - туда ведь он был добавлен раньше, чем в Group 1, и обновляется как раз эта запись). И вот я не очень понимаю как эту проблему порешить, вообще не понимаю. Почему он обновляет запись не с нужными _id друга, я же явно указываю его _id ("friends._id":friend), и он точно верный? Ощущение что вообще полностью игнорируется моё конкретное указание _id друга, поэтому и обновляется первая запись с нужным group_id.

В чём парадокс - добавление в группу у меня происходит почти таким же запросом (в случае когда друг был в списке, но потом мы его удалили и теперь надо просто поставить state = 1):
collection.update({_id:owner,"friends._id":friend,"friends.group_id":group_id}, {$set:{"friends.$.state":1,"friends.$.add_date":addDate}});
И ОНО РАБОТАЕТ!Не работает, сейчас перепроверил. До этого обновлял сам специально первого пользователя в списке (в данном случае удалял и добавлял Людмилу), в этом случае всё работает. А вот если я в базе сам ручками поставлю Алексею state = 1 в группе Group 1 (Алексей идёт второй записью с данной группой) и потом попробую его добавить - происходит точно тоже самое что и при удалении, обновляется первая запись с данной группой (то есть обновляется Людмила). WTF?
Я понимаю что проблема скорее всего в неправильном использовании мной вот этой конструкции:
"friends.$.state":1
, конкретно $. Но до введения правила "один пользователь в многих группах" оно работало как надо - и добавляло, и удаляло как надо. Проблемы начались когда начал указывать group_id в update.

На php+mysql, кстати, работает Но там я делал несколько по другому, ведь была отдельная таблица friends, соответственно там надо было просто найти запись с нужным friend_id и group_id, и, поставить ей state = 0.

У меня есть вариант как это сделать на ноде+монго чтоб 100% работало, но мне от чего-то кажется что он слегка черезжопный. Заключается вариант в том, что надо не пытаться апдейтить элемент массива friends в базе, а вытащить этот массив, "вживую" его проапдейтить и записать полностью на место старого. Реализовал сейчас временно такое "удаление", работает. Но не верю что нельзя вот так апдейтить как я выше пытался, явно должен быть способ.
__________________
Main PC:
Intel Core i5 4260U 1.44 GHz + LPDDR3 1x4096 1600 MHz + Intel HD Graphics 5000.

Asus Ёжик T101-MT:
Intel Atom N-570 1.66 Ghz + DDR2 2x1024 800 Mhz + Intel GMA 3150 128 Mb DDR2


Скачать Doom 2D: Remake v0.3.8a

Последний раз редактировалось St_AnGer, 26.10.2015 в 12:44.
(Offline)
 
Ответить с цитированием