Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get particular element from mongoDB array [duplicate]

Tags:

arrays

mongodb

I have mongo collection like below

{
  "auther" : "xyz" , 
  "location" : "zzz" , 
  "books" : 
    [
      {"book1" : "b1" , "date" : 2-3-00} ,
      {"book1" : "b2" , "date" : 4-9-00}
    ]
}

{
  "auther" : "pqr",
  "location" : "zzz" , 
  "books" : 
    [
      {"book1" : "b1" , "date" : 2-4-00}
    ]
}

I want to get the only the date of book b1 and author xyz .

i have make query like below

db.coll.find({"auther" : "xyz" , "books.book1" : "b1"} , {"books.date" : 1})

but it's gives output as follows

"books" : {"date" : 2-4-00} , "books" : {"date" : 4-9-00}

I want to get the only the date of book b1 and other xyz .means only "books" : {"date" : 2-4-00}

is it possible in mongo or am I doing something wrong?

like image 357
Swapnil Sonawane Avatar asked Apr 06 '11 06:04

Swapnil Sonawane


People also ask

How do you get a specific object from an array in MongoDB?

To search the array of object in MongoDB, you can use $elemMatch operator. This operator allows us to search for more than one component from an array object.

How do you find duplicate objects in an array?

Using the indexOf() method In this method, what we do is that we compare the index of all the items of an array with the index of the first time that number occurs. If they don't match, that implies that the element is a duplicate. All such elements are returned in a separate array using the filter() method.

How can I get distinct values from a field in MongoDB?

To get distinct values, use distinct() in MongoDB. It finds the distinct values for a specified field across a single collection or view and returns the results in an array.


2 Answers

The MongoDB query language is designed to return all matching Documents.

There is no support for returning only sub-documents.

This issue has an outstanding ticket in MongoDB's ticket tracker.


UPDATE: it looks like the ticket has been marked as fixed.

See here for an example of how to use this.

like image 85
Gates VP Avatar answered Oct 16 '22 21:10

Gates VP


It can be done using map/reduce, just emit the sub element into a temporary inline collection. Its a Hack and it works however I'd advise against it as map/reduce is single threaded, and has a large overhead for what you want to achieve, it is much easier to just extract the sub-element in your application.

Something like this...

map:

m = function() { 
    this.books.forEach(function(book){ 
        if(book1 == 'b1'){
           emit("books", {date: book.date,});
         }
     });
}

reduce:

r = function(key, values) {
      return this;
    }

query:

    db.coll.mapReduce(m, r, {query : {"auther" : "xyz" , "books.book1" : "b1"}, out: { inline : 1}})

like image 5
bm_i Avatar answered Oct 16 '22 20:10

bm_i