Простой запрос MongoDB к ХЭШУ работает не так, как ожидалось (только в некоторых условиях)

#ruby-on-rails-3 #mongodb #mongoid #mongodb-ruby

#ruby-on-rails-3 #mongodb #mongoid #mongodb-ruby

Вопрос:

Хорошо, это немного сложно, поэтому я постараюсь внести ясность.

У меня есть структура, которую я использую для создания какой-то системы тикетов.

Родительская коллекция: поток

Встроенная коллекция: сообщение (поток встраивает 0 .. N сообщений)

В сообщении у меня есть атрибут «read_time» типа HASH, где ключами являются OID пользователя, а значениями — datetime. Примерный набор данных для потока будет выглядеть так

 _id                   "4e9806c223349f0001000044" 
author_id            {"$oid": "4e8b281429e167765d00001a"} 
created_at           2011-10-14 09:54:10 UTC 
ref                  252 
status       "open" 
... 
messages 
                    [ 
                      0 
                          { 
                          _id                  {"$oid":     "4e9806c223349f0001000045"} 
                          author_id            {"$oid":     "4e8b281429e167765d00001a"} 
                          content              "Hello" 
                          created_at    2011-10-14 09:54:11 UTC 
                          read_time 
                                               { 
                                                     4e8b281429e167765d00001a           2011-10-14 09:54:11 UTC
                                                     4d5a7dfe29e1674958000013           2011-10-14 11:48:18 UTC
                                                     4d5a62ac29e1676226000050     2011-10-15 06:44:21 UTC 
                                               } 
                          }, 
                    1 
                          { 
                          _id                  {"$oid":   "4e9806c223349f0001000046"} 
                          author_id            {"$oid":   "4e8b281429e167765d00001a"} 
                          content              "Hello 2" 
                          created_at    2011-10-14 09:54:11 UTC 
                          read_time 
                                               { 
                                                     4e8b281429e167765d00001a           2011-10-15 09:54:11 UTC 
                                                     4d5a7dfe29e1674958000013           2011-10-16 11:48:18 UTC 
                                               } 
                          } 
                    ] 
  

Идея здесь состоит в том, чтобы создать запрос только к НЕПРОЧИТАННЫМ потокам
для данного автора. В приведенном выше примере пользователь с OID
4d5a62ac29e1676226000050 прочитал первое сообщение потока, но
не второе (поскольку хэш read_time не содержит записи для
ключа «4d5a62ac29e1676226000050»).

Мой запрос выглядит следующим образом, что, на мой взгляд, довольно прямолинейно и должно работать безупречно, но результаты довольно неожиданны….

 { "support_messages.read_time.4d5a62ac29e1676226000050" : { "$exists" : false} } 
  

Проще говоря, я запрашиваю все потоки, содержащие хотя бы одно сообщение
, у которого нет ключа «4d5a62ac29e1676226000050» в его
атрибуте read_time.

Странная часть сейчас … заключается в том, что этот запрос работает, но не всегда! Он возвращает только подмножество потоков, которые я ожидаю увидеть. Я еще не смог определить точный шаблон для случаев, которые не работают, но кажется, что когда в потоке более одного сообщения и что «многие» другие пользователи их прочитали, но не пользователь, к которому я запрашиваю, тогда рассматриваемый поток не работает.появляется в результатах… Я понятия не имею, почему. Если я запрашиваю документы вручную, я вижу все ожидаемые данные (как в примере выше), но поток просто игнорируется…

Пожалуйста, помогите!

Алекс

Комментарии:

1. После множества тестов во всех возможных направлениях, которые я мог, кажется, что следующий запрос работает правильно для моей цели: { «messages» => { «$elemMatch» => { «read_time.#{u.id.to_s}» => { «$exists» =>false}}}} Но для меня это не имеет смысла … добавление $elemMatch не должно иметь абсолютно никакого значения, поскольку в запросе есть только «один» атрибут?? Алекс

Ответ №1:

Если я правильно понимаю, вы хотите 4e8b281429e167765d00001a , 4d5a7dfe29e1674958000013 , 4d5a62ac29e1676226000050 быть ключами внутреннего хэша под первым read_time . Но я не вижу никакого двоеточия между (скажем) 4e8b281429e167765d00001a и 2011-10-14 09:54:11 UTC .

Я бы ожидал, что это будет:

 read_time 
{
   4e8b281429e167765d00001a : 2011-10-14 09:54:11 UTC
   4d5a7dfe29e1674958000013 : 2011-10-14 11:48:18 UTC
   4d5a62ac29e1676226000050 : 2011-10-15 06:44:21 UTC 
}