Chcę zapytanie w MongoDB, które wykonuje następujące czynności:

  • Dokument zwrócony właściwość profession.organization może być ciągiem znaków „bank”.
  • Dokument zwrócony właściwość profession.city może być ciągiem znaków „NY”.
  • Jeśli jednak w dokumencie występuje słowo „bank” dla „zawód.organizacja” ORAZ „NY” dla słowa „zawód.miasto”, dokument należy wykluczyć.

Podsumowując, dokument może mieć miasto „NY” lub „bank” organizacji, ale należy go wykluczyć, jeśli jednocześnie posiada te właściwości.

Czego próbowałem do tej pory.

    targetObj = await db.db(MDBC.db).collection(MDBC.pC)
        .aggregate([{
            $match: {
                $and: [
                { 'profession.organization': { $ne: 'bank' } }, 
                { 'profession.city': { $ne: 'NY' } }
              ]
            }
        }, { $sample: { size: 1 } }]).next();
2
Willem van der Veen 1 kwiecień 2020, 15:29

3 odpowiedzi

Najlepsza odpowiedź

Spróbuj tego:

targetObj = await db.db(MDBC.db).collection(MDBC.pC)
 .aggregate([
  {
    $match: {
      $and: [
        {
          $or: [
            { "profession.organization": "bank" },
            { "profession.city": "NY" }
          ]
        },
        {
          $or: [
            {
              "profession.organization": "bank",
              "profession.city": { $ne: "NY" }
            },
            {
              "profession.organization": { $ne: "bank" },
              "profession.city": "NY"
            }
          ]
        }
      ]
    }
  },
  { $sample: {size: 1} } ]).next();

MongoPlayground

2
Valijon 1 kwiecień 2020, 12:50

Myślę, że zapytanie użyte w zaakceptowanej odpowiedzi mogłoby być znacznie krótsze.

db.collection.aggregate([
  {
    $match: {
      $or: [
        {
          "profession.organization": "bank",
          "profession.city": {
            $ne: "NY"
          }
        },
        {
          "profession.organization": {
            $ne: "bank"
          },
          "profession.city": "NY"
        }
      ]
    }
  },
  {
    $sample: {
      size: 1
    }
  }
])

I jeszcze jedno, co chcę powiedzieć, to jeśli chcesz dołączyć dokumenty, które nie mają żadnej z tych dwóch właściwości, powinieneś użyć tego:

db.collection.aggregate([
  {
    $match: {
      $or: [
        {
          "profession.organization": "bank",
          "profession.city": {
            $ne: "NY"
          }
        },
        {
          "profession.organization": {
            $ne: "bank"
          },
          "profession.city": "NY"
        },
        {
          "profession.organization": {
            $ne: "bank"
          },
          "profession.city": {
            $ne: "NY"
          }
        }
      ]
    }
  },
  {
    $sample: {
      size: 1
    }
  }
])

Będzie to również obejmować dokumenty takie jak:

  {
    "profession": {
      "organization": "someBank",
      "city": "notNA"
    }
  }
0
Ramesh Reddy 1 kwiecień 2020, 13:18

Niestety, w chwili pisania tego tekstu nie ma operatora dopasowującego w MongoDB, który mógłby w tym pomóc. Możesz jednak osiągnąć podobny wynik, łącząc operatory $or i $ne. Wypróbuj coś takiego dla swojego zapytania:

const query = {
  $or: [
    {
      // Include all non-banks outside of NY.
      'profession.city': { $ne: 'NY' },
      'profession.organization': { $ne: 'bank' }
    },
    {
      // Include all non-banks in NY.
      'profession.city': 'NY',
      'profession.organization': { $ne: 'bank' }
    },
    {
      // Include all banks outside of NY.
      'profession.city': { $ne: 'NY' },
      'profession.organization': 'bank'
    }
  ]
};
0
Fredric 1 kwiecień 2020, 13:43