2015-01-12 3 views
0

Мне действительно нужно понять, сделал ли я сломанный дизайн, или просто не нашел правильного решения. Документ, в моей коллекции выглядит следующим образом:Совокупный конвейер MongoDB и соответствие поля

{ 
    "_id" : { 
    "owner" : "[email protected]", 
    "day" : 5.0, 
    "month" : 0.0 
    }, 
    "value" : { 
    "userId" : 7.0, 
    "session" : 5.0, 
    "no_closed" : 1.0, 
    "data" : { 
     "sentMessage" : [{ 
      "adId" : 19.0, 
      "detail" : { 
      "timestamp" : 1420806952000.0 
      } 
     }, { 
      "adId" : 19.0, 
      "detail" : { 
      "timestamp" : 1420806969000.0 
      } 
     }], 
     "receivedMessage" : [{ 
      "adId" : 1.0, 
      "detail" : { 
      "timestamp" : 1420806955000.0 
      } 
     }] 
    } 
    } 
} 

Что мне нужно, чтобы получить все документы, где поле sentMessage aapId матчей в receivedMessage APPID. Представьте, что пользователи используют разные приложения для сообщения друг с другом через один и тот же сервер, и мне нужно найти сообщения, которые были отправлены и получены пользователем через одно и то же приложение через определенный промежуток времени.

Благодаря

+0

Нет, это не похоже на то, что это некорректная структура. Ваша реальная структура важна для вашего вопроса. Пожалуйста исправьте. Что он? «SentMessage» и «receivedMessage» в том же документе для элемента массива? Или они разные элементы массива. По крайней мере, нужно быть в документе. –

+3

Пожалуйста, напишите мне сообщение, когда вы закончите редактирование. Структура здесь изменилась больше, чем лицо Майкла Джексона. –

+0

Сделано :) это копия-паста из db. –

ответ

1

Да ну появляется ваше поле будет называться «Адид», а не «aapId», как вы утверждаете. Не очень помогло, чтобы вы не представили образец данных для положительного совпадения. Но о хорошо ...

В основном с использованием операторов $map и $anyElementTrue для перемещения элементов массива для логического сравнения.

Не идеально, потому что вы полагаетесь на проекцию из структуры агрегации, чтобы решить, имеют ли элементы в массиве соответствующие условия. Кроме того, можно закодировать это в JavaScript с , но это, вероятно, еще хуже производительность благодаря оценке кода и объекта преобразования JavaScript:

db.collection.aggregate([ 
    { "$project": { 
     "value": 1, 
     "matched": { 
      "$anyElementTrue": [ 
       { "$map": { 
        "input": "$value.data.sentMessage", 
        "as": "sent", 
        "in": { 
         "$anyElementTrue": [ 
          { "$map": { 
           "input": "$value.data.receivedMessage", 
           "as": "received", 
           "in": { 
            "$eq": [ "$$sent.adId", "$$received.adId" ] 
           } 
          }} 
         ] 
        } 
       }} 
      ] 
     } 
    }}, 
    { "$match": { "matched": true } } 
]) 

Простой принцип. Сравните каждый элемент массива с каждым элементом массива и ищите возможность по крайней мере одного совпадения. Тогда результат true и просто верните те, которые соответствуют условиям.

Смежные вопросы