Запрос MongoDB с использованием значений приоритета - PullRequest
1 голос
/ 24 апреля 2020

В моей коллекции есть следующие документы:

/* 1 */
{
    "_id" : ObjectId("5ea32d11f213c27c35395fd3"),
    "name" : "Test",
    "state" : "OH",
    "code" : "CDM"
}

/* 2 */
{
    "_id" : ObjectId("5ea32d29f213c27c35395fe0"),
    "name" : "Test1",
    "state" : "ALL",
    "code" : "CDM"
}

/* 3 */
{
    "_id" : ObjectId("5ea32d38f213c27c35395fe7"),
    "name" : "Test2",
    "state" : "OH",
    "code" : "ALL"
}

/* 4 */
{
    "_id" : ObjectId("5ea32d46f213c27c35395feb"),
    "name" : "Test3",
    "state" : "ALL",
    "code" : "ALL"
}

Попытка отфильтровать документы на основе state и code.

Но есть несколько критериев, в частности state или code не найден, затем выполните поиск по значению ALL

Пример 1:

состояние = CA

код = CDM

, затем только возврат

  {
    "_id" : ObjectId("5ea32d29f213c27c35395fe0"),
    "name" : "Test1",
    "state" : "ALL",
    "code" : "CDM"
}

Пример 2:

состояние = CA

код = DCM

, затем возвращаются только

  {
    "_id" : ObjectId("5ea32d46f213c27c35395feb"),
    "name" : "Test3",
    "state" : "ALL",
    "code" : "ALL"
}

et c ..

Запрос, который я пробовал, был состоянием = CA, код = CDM:

db.getCollection('user_details').aggregate([

{'$match': { 'state': {'$in': ['CA','ALL']},
'code': {'$in': ['CDM','ALL']}}}

])

Возврат был:

/* 1 */
{
    "_id" : ObjectId("5ea32d29f213c27c35395fe0"),
    "name" : "Test1",
    "state" : "ALL",
    "code" : "CDM"
}

/* 2 */
{
    "_id" : ObjectId("5ea32d46f213c27c35395feb"),
    "name" : "Test3",
    "state" : "ALL",
    "code" : "ALL"
}

Ожидаемое было:

{
        "_id" : ObjectId("5ea32d29f213c27c35395fe0"),
        "name" : "Test1",
        "state" : "ALL",
        "code" : "CDM"
    }

Не могли бы вы помочь решить эту проблему.

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Попробуйте это:

db.user_details.aggregate([
  {
    $facet: {
      match: [
        {
          "$match": {
            $or: [
              {
                "state": "CA",
                "code": {
                  "$in": [ "CDM", "ALL" ]
                }
              },
              {
                "state": {
                  "$in": [ "CA", "ALL"]
                },
                "code": "CDM"
              }
            ]
          }
        }
      ],
      all: [
        {
          "$match": {
            "state": "ALL",
            code: "ALL"
          }
        }
      ]
    }
  },
  {
    $project: {
      match: {
        $cond: [
          {
            $eq: [ { $size: "$match" },  0]
          },
          "$all",
          "$match"
        ]
      }
    }
  },
  {
    $unwind: "$match"
  },
  {
    $replaceWith: "$match"
  }
])

MongoPlayground

1 голос
/ 24 апреля 2020

Попробуйте запрос ниже:

db.collection.find({
  $or: [
    {
      state: "CA",
      code: "CDM"
    },
    {
      state: "ALL",
      code: "CDM"
    },
    {
      state: "ALL",
      code: "ALL"
    },
    {
      state: "CA",
      code: "ALL"
    }
  ]
})

Таким образом, в принципе вы не можете достичь того, что ищете в одном запросе, вы можете попробовать оператор агрегирования $ facet & $ переключитесь , чтобы сделать это, но я бы не предпочел сделать это, потому что каждый этап в фасете будет выполнять данную операцию над данными всей коллекции. Вместо этого получите меньше документов, используя запрос выше, и в своем коде вы можете отфильтровать для наиболее подходящего do c, что было бы легко и эффективно. Не забудьте сохранить индексов в БД.

Тест: mongoplayground

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...