Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match documents with fields not containing values in array

After some "match" steps in db.collection.aggregate I got

{_id: 1, field1: "a", field2: ["1.1.1", "1.1.2", "1.1.3", "1.1.4"]}
{_id: 2, field1: "b", field2: [         "1.1.2",          "1.1.4"]}
{_id: 3, field1: "c", field2: ["1.1.1", "1.1.2"                  ]}
{_id: 4, field1: "d", field2: [                           "1.1.4"]}
{_id: 5, field1: "e", field2: [                  "1.1.3"         ]}

// I made preformatting

I want to apply yet another rule (I suppose it would be "group" rule) in aggregate to get all documents where "field2" does not contain "1.1.1" OR "1.1.4". So I need documents without "1.1.1" OR "1.1.4" OR ("1.1.1" AND "1.1.4").

I want to get something like this:

{_id: 5, field1: "e", field2: [                  "1.1.3"         ]}

So, I have field2, which is array in each document, and I want to get all the documents which have no single element in a given array (e.g. ["1.1.1", "1.1.4"]).

P.S. I need this for "single statement aggregation command". No additional JS accepted.

UPD

@blakes-seven , tnx

My mistake is that I used

{ "$match": { "field2": { "$elemMatch": { "$nin": ["1.1.1","1.1.4"] } } } }

but right thing is just to use

{ "$match": { "field2": {                 "$nin": ["1.1.1","1.1.4"] } } }

Don't overestimate $elemMatch :)

like image 871
Burlaka Sergey Avatar asked Sep 11 '25 22:09

Burlaka Sergey


1 Answers

Actually all you need is a $nin in a $match:

{ "$match": { "field2": { "$nin": ["1.1.1","1.1.4"] } } }

It's also likely that there is even a better approach to getting that result before what you have reached in the pipeline, but since your question does not explain that then there is no way to tell.

like image 126
Blakes Seven Avatar answered Sep 16 '25 09:09

Blakes Seven