MongoDB query to retrieve a single value of an array by a value in an array

I have a set of documents, each of which contains an array of supporting documents. Each subdocument has a time value. I am trying to check if I can return a supporting document based on time in an additional document.

I know that I can get a supporting document using $ slice, but $ slice only gives a specific index, range and offset.

Sample time!

Documents are like ...

{ id: 1234, type: 'a', subs: [ { time: 123001, val: 'a' }, { time: 123002, val: 'b' }, { time: 123003, val: 'c' } ] } 

If I make a query with find ({}, {subs: {$ slice: [2,1]}}), I return something like:

 { id: 1234, type: 'a', subs: [{ time: 123002, val: 'b' }]} 

I want to get this record, for example, not based on an offset, but based on a time value of 123002.

Possible?

go!

+6
source share
1 answer

Since you developed the data, this is not possible.

In MongoDB, queries return the entire document. You can filter specific fields, but if the field value is an array, it stops.

When you have β€œarrays of objects,” you either have $slice , which is not what you want, or you will have to model your data in different ways.

In your case, the following structure will make your request possible:

 { _id: 1234, type: 'a', subs: { '123001': { val: 'a' }, '123002': { val: 'b' }, '123003': { val: 'c' } } } 

Notice how I changed subs to a JSON object instead of an array. Now you can execute the following query and get only the time you are looking for:

 find( { _id: 1234 }, { 'subs.123002': 1 } ) 

The obvious trade-off here is that you have to change the way you use the document. You cannot use $push on subs , you cannot request for {'subs.time': 1234} , instead you should request {'subs.1234': { $exists:true} } .

+4
source

Source: https://habr.com/ru/post/891875/


All Articles