Поиск MongoDB во вложенном массиве - PullRequest
2 голосов
/ 18 июня 2020

У меня есть подобная структура коллекции (с образцами данных):

{
    name: "Billie Jean",
    active: false,
    ranges: [
        { sfeMin: -6.75 , sfeMax: -7 , cilMin: 0.75 , cilMax: 0.75 },
        { sfeMin: -7.25 , sfeMax: -7.5 , cilMin: 1.25 , cilMax: 1.25 },
        { sfeMin: -7.5 , sfeMax: -7.75 , cilMin: 1.5 , cilMax: 1.5 },
        { sfeMin: -7.75 , sfeMax: -8 , cilMin: 1.75 , cilMax: 1.75 },
        { sfeMin: -6.5 , sfeMax: -6.75 , cilMin: 0.5 , cilMax: 0.5 },
        { sfeMin: -7 , sfeMax: -7.25 , cilMin: 0 , cilMax: 0 }
    ]
},
{
    name: "Louis Armstrong",
    active: true,
    ranges: [
        { sfeMin: -8 ,sfeMax: 8 , cilMin: 0 , cilMax: 6 },
        { sfeMin: -8 ,sfeMax: 8 , cilMin: 0 , cilMax: 6 },
        { sfeMin: -8 ,sfeMax: 8 , cilMin: 0 , cilMax: 6 },
        { sfeMin: -8 ,sfeMax: 8 , cilMin: 0 , cilMax: 6 }
    ]
}

(это несколько примеров данных, вставленных в коллекцию).

Мне нужно выполнить поиск если элемент внутри этой коллекции активен и имеет значение, назовем его x, которое находится между sfeMin и sfeMax и другим значением, назовем его y, которое находится между cilMin и cilMax.

Имея x = - 8 и y = 0, используя этот фильтр:

{ $and: [{ active: true }, { 'ranges.sfeMin': { $gte: -8 } }, { 'ranges.sfeMax': { $lte: -8 } }, { 'ranges.cilMin': { $gte: 0 } }, { 'ranges.cilMax': { $lte: 0 } } ]}

не должно найти никакого значения.

Но при удалении {active: false} или переключении значения всех записей на true для активных, запрос возвращает элемент коллекции с именем «Bill ie Jean», чего не должно быть (по крайней мере, в моем желаемом поведении) .

Давайте шаг за шагом отработаем запрос для рассматриваемой записи:

  • все sfeMin> = -8
  • единственные sfeMax <= -8 является четвертой записью массива диапазонов (-8) </li>
  • для этой строки (с sfeMin = -7.75 и sfeMax = -8) cilMin> = 0 (на самом деле 1.75), но cilMax НЕ <= 0 (опять же 1,75). </li>

Похоже, MongoDB обрабатывает массив диапазонов как одну сглаженную запись вместо того, чтобы выполнять запрос в массиве построчно. Рассмотрение массива как единой большой картины - это нормально, чтобы считать запрос действительным для Билла ie, потому что все значения присутствуют и верны, но занесены в разные строки массива.

Это не то, что я ищу для.

1 Ответ

2 голосов
/ 18 июня 2020

Проблема в том, как вы это сделали, в том, что запрос НЕ будет знать, что фильтры диапазонов должны быть частью одного и того же объекта, он будет просматривать все объекты массива, независимо от того, есть ли они в одном объекте.

Ваш запрос запрашивает документы, в которых массив ranges имеет хотя бы один встроенный документ, содержащий поле sfeMin gte to -8, и хотя бы один внедренный документ (но не обязательно тот же внедренный документ), который содержит поле sfeMax, равное до -8 и так далее

Я не тестировал, но думаю, что это должно быть так:

{
  active: true,
  ranges: { $elemMatch: { sfeMin: { $gte: -8 }, sfeMax: { $lte: -8 }, cilMin: { $gte: 0 }, cilMax: { $lte: 0 } }}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...