Mongodb find inside sub array

前端 未结 1 1350
名媛妹妹
名媛妹妹 2021-01-11 18:06

I have a document that\'s setup like this:

{
  _id : ObjectId(),
  info : [ 
        [ 
            1399583281000, 
         


        
相关标签:
1条回答
  • 2021-01-11 18:20

    Your on the right track, but there are a few things to note here, aside from the part that nested arrays ( and especially with anonymous keys) are not exactly a great way to store things, but as long as you consistently know the position then that should be reasonably okay.

    There is a distinct difference between matching documents and matching "elements of an array". Though your current value would actually not match (your search value is not within the bounds of the document), if the value actually was valid your query correctly matches the "document" here, which contains a matching element in the array.

    The "document" contains all of the array elements, even those that do not match, but the condition says the "document" does match, so it is returned. If you just want the matching "elements" then use .aggregate() instead:

        db.infos.aggregate([
            // Still match the document
            { "$match": { 
                "info": { 
                    "$elemMatch": { "0": {"$gte": 1399583285000} }
                }
            }},
    
            // unwind the array for the matched documents
            { "$unwind": "$info" },
    
            // Match only the elements
            { "$match": { "info.0": { "$gte": 1399583285000 } } },
    
            // Group back to the original form if you want
            { "$group": {
                "_id": "$_id",
                "info": { "$push": "$info" }
            }}
    
        ])
    

    And that returns just the elements that matched the condition:

    {
        "_id" : ObjectId("536c1145e99dc11e65ed07ce"),
        "info" : [
                [
                        1399583285000,
                        20.13
                ],
                [
                        1399583286000,
                        20.13
                ]
        ]
    }
    

    Or course if you only ever expected one element to match, then you could simply use projection with .find()**:

    db.infos.find(
        {
           "info":{
              "$elemMatch":{
                 "0": {
                    "$gt": 1399583285000
                 }
              }
           }
        },
        {
            "info.$": 1
        }
    )
    

    But with a term like $gt you are likely to get multiple hits within a document so the aggregate approach is going to be safer considering that the positional $ operator is only going to return the first match.

    0 讨论(0)
提交回复
热议问题