Mongo complex query problem

  mongodb, question

Original json

{
 "_id" : ObjectId("58b3a8dc96fbc7cfb8287093"),
 "name": "Groundwater Quality Standard",
 "GBNumber" : "GB/T 14848-93",
 "dataEntryClerk" : "handsomeboy",
 "lastModified" : "Fri Feb 27 2017 12:03:40 GMT+0800",
 "contents" : [
 {
 "standardID" : "9527-01",
 "unit" : "mg/L",
 "classifications" : [
 {
 "level" : "I",
 "upperLimit" : "0",
 "lowerLimit" : "50"
 },
 {
 "level" : "II",
 "upperLimit" : "50",
 "lowerLimit" : "150"
 },
 {
 "level" : "III",
 "upperLimit" : "150",
 "lowerLimit" : "250"
 },
 {
 "level" : "IV",
 "upperLimit" : "250",
 "lowerLimit" : "350"
 },
 {
 "level" : "V",
 "upperLimit" : "350",
 "lowerLimit" : "-1"
 }
 ]
 },
 {
 "standardID" : "7439-89-6",
 "unit" : "mg/L",
 "classifications" : [
 {
 "level" : "I",
 "upperLimit" : "0",
 "lowerLimit" : "0.1"
 },
 {
 "level" : "II",
 "upperLimit" : "0.1",
 "lowerLimit" : "0.2"
 },
 {
 "level" : "III",
 "upperLimit" : "0.2",
 "lowerLimit" : "0.3"
 },
 {
 "level" : "IV",
 "upperLimit" : "0.3",
 "lowerLimit" : "0.4"
 },
 {
 "level" : "V",
 "upperLimit" : "0.5",
 "lowerLimit" : "-1"
 }
 ]
 }
 ]
 }

Want to find out the results:

{
 "contents" : [
 {
 "standardID" : "9527-01",
 "unit" : "mg/L",
 "classifications" : [
 {
 "level" : "I",
 "upperLimit" : "0",
 "lowerLimit" : "50"
 },
 {
 "level" : "II",
 "upperLimit" : "50",
 "lowerLimit" : "150"
 },
 {
 "level" : "III",
 "upperLimit" : "150",
 "lowerLimit" : "250"
 },
 {
 "level" : "IV",
 "upperLimit" : "250",
 "lowerLimit" : "350"
 },
 {
 "level" : "V",
 "upperLimit" : "350",
 "lowerLimit" : "-1"
 }
 ]
 }
 ]
 }

Please tell me how to write Daniel. XXX. find ()

Let’s make a comment first:

Ask questions, putminimizeTheReproducibleIt is good to put out examples of problems. You put such a long document here, and everyone is very tired.


What you need is actually to returnSome specific documents in the arrayInstead of the entire array.

If youOnly one element in the array needs to be returned

db.xxx.find(
 {'contents.standardID': '9527-01'},
 {contents: {$elemMatch: {standardID: '9527-01'}}, _id: 0}
 )

The first row is the query criteria and the second row is the filter criteria. It can be seen that operators can also be used in filtering conditions. But this operatorOnly the first element satisfying the condition will be returned, andVersion 2.2 or above is requiredMongoDB.

Or use$Subscript selector:

db.xxx.find(
 {'contents.standardID': '9527-01'},
 {'contents.$': 1, _id: 0}
 )

The query criteria in the above example can also be used$elemMatch.

If you need to return multiple matching elements in the array:

2$unwind

By putting$unwindCome oncontentsOperate as an independent document stream. See @bguo’s answer for the code.
However, if your array is large, it will cause performance problems.

3$filter

This is a3.2The new operator in the version is used to filter the returned content.

db.xxx.aggregate(
 {$match: {'contents.standardID': '9527-01'}},
 {$project: {
 contents: {$filter: {
 input: '$contents',
 as: 'contents',
 cond: {$eq: ['$$contents.standardID', '9527-01']}
 }},
 _id: 0
 }}
 )

Of course, you can still use it$redact(Version 2.6), ormapReduce()And so on a variety of methods.