2

Hello I have json data like that:

{ 
   "_id":ObjectId('5dfe907f80580559fedcc9b1'),
   "companyMail":"mail@gmail.com"
   "workers":[ 
      { 
         "name":name,
         "surName":surname,
         "mail":"mail2@gmail.com",
         "password":"password",
         "companyMail":"mail@gmail.com",
      }
   ]

}

And I want to get an worker from workers:

 { 
     "name":name,
     "surName":surname,
     "mail":"mail2@gmail.com",
     "password":"password",
     "companyMail":"mail@gmail.com",
  }

I'm writing this query:

collection.findOne({
      'companyMail':"mail@gmail.com",
      'workers.mail':"mail2@gmail.com",

      });

But it gives me whole of data. I only want to get worker which I search. How can I do that with Mongo Dart. https://pub.dev/packages/mongo_dart

Onur
  • 318
  • 4
  • 12

3 Answers3

1

I found the solution. We should use aggregation but we should add some specific query to get one result. In dart mongo, we can use Filter object to add. Like that:

            final pipeline = AggregationPipelineBuilder()
      .addStage(Match(where.eq('companyMail', companyMail).map['\$query']))
      .addStage(Match(where.eq('customers.mail', customerMail).map['\$query']))
      .addStage(Project({
        "_id": 0, //You can use as:'customer' instead of this keyword.
        "customers": Filter(input: '\$customers',cond: {'\$eq':["\$\$this.mail",customerMail]}).build(),
      }))
      .build();
  final result = await DbCollection(_db, 'Companies')
      .aggregateToStream(pipeline)
      .toList();
Onur
  • 318
  • 4
  • 12
0

mongo-dart API driver is very bad and there is no good documentation whereas mongo-node.js API driver is very good and has very good documentation, so better to do server side with node, for example in node your problem will solve by one line code:

    collection.find(
    {
      'companyMail':"mail@gmail.com",
      'workers.mail':"mail2@gmail.com",
    }).project({
    '_id':0, 'workers':1
    });
Tom William
  • 81
  • 1
  • 3
-1

Pass options to project the workers field only

   db.company.findOne(
     {
        'companyMail':"mail@gmail.com",
        'workers.mail':"mail2@gmail.com",
      },
     {
         "workers":1,
         _id:0
     }
    );

In mongo-dart , looking at their api, you can use aggregation which is as follows

  final pipeline = AggregationPipelineBuilder()
    .addStage(Match(where.eq('companyMail','mail@gmail.com')))
    .addStage(Project({
                  '_id': 0,
                  "workers":1,
                })).build())

  final result =
     await DbCollection(db, 'company')
       .aggregateToStream(pipeline).toList();
  // result[0] should give you one worker
Shambu
  • 2,612
  • 1
  • 21
  • 16
  • You cannot do that in mongo dart. When I write this code it gives me error: "Too many positional arguments: 1 expected, but 2 found. Try removing the extra arguments." findOne() function only getting Map or Selector Builder and one argument. – Onur Dec 23 '19 at 11:18
  • your projection will return all workers for the matching filter – Ayoub Dec 23 '19 at 11:24
  • Also second option didn't work. It throw error:"Exception: Not implemented for SelectorBuilder({$query: {companyMail: mail@gmail.com}})" ? – Onur Dec 23 '19 at 11:42