Запрос, сравнивающий массивы объектов

1

Мне интересно, как я могу сравнивать массивы (вложенных) объектов в Mongoose.

Учитывая приведенные ниже данные, я хотел бы получить результаты, когда свойства name совпадают. Может ли кто-нибудь помочь мне с этим?

    Organisation.find( { 
        $or: [ 
          { "category_list": { $in: cat_list } }, 
          { "place_topics.data": { $in: place_tops } } 
        ] 
      } 
    )

Скажем, что это данные, хранящиеся в моем MongoDB:

  "category_list": [
      {
          "id": "197750126917541",
          "name": "Pool & Billiard Hall"
      },
      {
          "id": "197871390225897",
          "name": "Cafe"
      },
      {
          "id": "218693881483234",
          "name": "Pub"
      }
  ],
  "place_topics": {
      "data": [
          {
              "name": "Pool & Billiard Hall",
              "id": "197750126917541"
          },
          {
              "name": "Pub",
              "id": "218693881483234"
          }
      ]
  }

И пусть говорят, что это массивы, которые я хочу сравнить (почти одинаковые данные):

let cat_list = [
            {
                "id": "197750126917541",
                "name": "Pool & Billiard Hall"
            },
            {
                "id": "197871390225897",
                "name": "Cafe"
            },
            {
                "id": "218693881483234",
                "name": "Pub"
            }
        ]
let place_tops = [
                {
                    "name": "Pool & Billiard Hall",
                    "id": "197750126917541"
                },
                {
                    "name": "Pub",
                    "id": "218693881483234"
                }
            ]
  • 0
    Верно ли следующее? У нас есть совпадение только в том случае, если: - массивы для сравнения имеют ту же длину, что и соответствующие им массивы; - они содержат одинаковый набор идентификаторов; - записи с одинаковым идентификатором должны иметь одинаковое имя, другие поля могут быть разными.
  • 0
    На самом деле, данные, хранящиеся в MongoDB, также содержат строку _id, поэтому она ложна.
Показать ещё 2 комментария
Теги:
mongoose
mongodb-query

1 ответ

2
Лучший ответ

Когда для каждого элемента массива требуется "несколько условий", вы фактически используете $elemMatch, и на самом деле "нужно", иначе вы не соответствуете правильному элементу.

Поэтому, чтобы применить несколько условий, вы предпочтете создать массив условий для $or вместо ярлыков с $in:

Organizations.find({
  "$or": [].concat(
    cat_list.map( c => ({ "category_list": { "$elemMatch": c } }) ),
    place_tops.map( p => ({ "place_topics": { "$elemMatch": p } }) )
  )
})

Однако, если вы сделаете шаг назад и подумаете логически об этом, вы на самом деле назвали одно из свойств "id". Это, как правило, подразумевает во всей хорошей практике, что ценность фактически "уникальна".

Поэтому все, что вам действительно нужно сделать, это просто извлечь эти значения и придерживаться исходной формы запроса:

Organizations.find({
  "$or": [
    { "category_list.id": { "$in": cat_list.map(c => c.id) } },
    { "place_topics.id": { "$in": place_tops.map(p => p.id) } }
  ]
})

Таким образом, просто сопоставляя как значения, так и свойство, чтобы "соответствовать" на значение "id". Это простая форма "точечной нотации", которая обычно достаточна, когда у вас есть одно условие для элемента массива для проверки/сопоставления.

Это, как правило, самый логичный подход, учитывая данные, и вы должны применить тот, который из них действительно соответствует условиям данных, которые вам нужны. Для "множественного" использования используйте $elemMatch. Но если вам не нужно несколько, потому что существует сингулярное совпадение, то просто выполните сингулярное совпадение

  • 0
    Это, кажется, делает свое дело, я использую последний подход, поскольку достаточно иметь одно совпадение в любом утверждении. Спасибо вам большое!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню