Mongodb - regex match of keys for subdocuments

后端 未结 2 428
攒了一身酷
攒了一身酷 2020-12-16 20:27

I have some documents saved in a collection (called urls) that look like this:

{
    payload:{
        url_google.com:{
            url:\'google         


        
相关标签:
2条回答
  • 2020-12-16 20:31

    It's not possible to query against document keys in this way. You can search for exact matches using $exists, but you cannot find key names that match a pattern.

    I assume (perhaps incorrectly) that you're trying to find documents which have a URL sub-document, and that not all documents will have this? Why not push that type information down a level, something like:

    {
      payload: {
        type: "url",
        url: "Facebook.com",
        ...
      }
    }
    

    Then you could query like:

    db.foo.find({"payload.type": "url", ...})
    

    I would also be remiss if I did not note that you shouldn't use dots (.) is key names in MongoDB. In some cases it's possible to create documents like this, but it will cause great confusions as you attempt to query into embedded documents (where Mongo uses dot as a "path separator" so to speak).

    0 讨论(0)
  • 2020-12-16 20:50

    You can do it but you need to use aggregation: Aggregation is pipeline where each stage is applied to each document. You have a wide range of stages to perform various tasks.

    I wrote an aggregate pipeline for this specific problem. If you don't need the count but the documents itself you might want to have a look at the $replaceRoot stage.

    db.getCollection('urls').aggregate([
        {
            // creating a nested array with keys and values
            // of the payload subdocument.
            // all other fields of the original document
            // are removed and only the filed arrayofkeyvalue persists
            "$project": {
                "arrayofkeyvalue": {
                    "$objectToArray": "$$ROOT.payload"
                }
            }
        },
        {
            "$project": {
                // extract only the keys of the array
                "urlKeys": "$arrayofkeyvalue.k"
            }
        },
        {
            // merge all documents
            "$group": {
                // _id is mandatory and can be set
                // in our case to any value
                "_id": 1,
                // create one big (unfortunately double
                // nested) array with the keys
                "urls": {
                    "$push": "$urlKeys"
                }
            }
        },
        {
            // "explode" the array and create
            // one document for each entry
            "$unwind": "$urls"
        },
        {
            // "explode" again as the arry
            // is nested twice ...
            "$unwind": "$urls"
        },
        {
            // now "query" the documents
            // with your regex
            "$match": {
                "urls": {
                    "$regex": /url_/
                }
            }
        },
        {
          // finally count the number of
          // matched documents
            "$count": "count"
        }
    ])
    
    0 讨论(0)
提交回复
热议问题