2014-04-07 3 views
5

में अंदर सरणी मैं regex के साथ MongoDB में एक सरणी के अंदर एक प्रश्न करना चाहते हैं, संग्रह इस तरह दस्तावेजों:Regex MongoDB

{ 
"_id" : ObjectId("53340d07d6429d27e1284c77"), 
"company" : "New Company", 
"worktypes" : [ 
    { 
     "name" : "Pompas", 
     "works" : [ 
      { 
       "name" : "name 2", 
       "code" : "A00011", 
       "price" : "22,22" 
      }, 
      { 
       "name" : "name 3", 
       "code" : "A00011", 
       "price" : "22,22" 
      }, 
      { 
       "name" : "name 4", 
       "code" : "A00011", 
       "price" : "22,22" 
      }, 
      { 
       "code" : "asdasd", 
       "name" : "asdads", 
       "price" : "22" 
      }, 
      { 
       "code" : "yy", 
       "name" : "yy", 
       "price" : "11" 
      } 
     ] 
    }, 
    { 
     "name" : "name 4", 
     "works" : [ 
      { 
       "code" : "A112", 
       "name" : "Nombre", 
       "price" : "11,2" 
      } 
     ] 
    },   
    { 
     "name" : "ee", 
     works":[ 

      { 
       "code" : "aa", 
       "name" : "aa", 
       "price" : "11" 
      }, 
      { 
       "code" : "A00112", 
       "name" : "Nombre", 
       "price" : "12,22" 
      } 
       ] 
    } 
] 

}

तब मैं ने एक दस्तावेज खोजने की जरूरत है कंपनी का नाम और इसके अंदर कोई भी काम कोड या नाम के काम में एक रेगेक्स से मेल खाता है। मैं इस है:

var companyquery = { "company": "New Company"}; 
var regQuery = new RegExp('^A0011.*$', 'i'); 

db.categories.find({$and: [companyquery, 
      {$or: [ 
       {"worktypes.works.$.name": regQuery}, 
       {"worktypes.works.$.code": regQuery} 
      ]}]}) 

लेकिन न वापसी किसी भी result..I लगता त्रुटि डी डॉट और $ .. किसी भी विचार के साथ सरणी के अंदर खोजने का प्रयास करते है?

संपादित करें:

इस के साथ:

db.categories.find({$and: [{"company":"New Company"}, 
      {$or: [ 
       {"worktypes.works.name": {"$regex": "^A00011$|^a00011$"}}, 
       {"worktypes.works.code": {"$regex": "^A00011$|^a00011$"}} 
      ]}]}) 

यह परिणाम है:

{ 
    "_id" : ObjectId("53340d07d6429d27e1284c77"), 
    "company" : "New Company", 
    "worktypes" : [ 
     { 
      "name" : "Pompas", 
      "works" : [ 
       { 
        "name" : "name 2", 
        "code" : "A00011", 
        "price" : "22,22" 
       }, 
       { 
        "code" : "aa", 
        "name" : "aa", 
        "price" : "11" 
       }, 
       { 
        "code" : "A00112", 
        "name" : "Nombre", 
        "price" : "12,22" 
       }, 
       { 
        "code" : "asdasd", 
        "name" : "asdads", 
        "price" : "22" 
       }, 
       { 
        "code" : "yy", 
        "name" : "yy", 
        "price" : "11" 
       } 
      ] 
     }, 
     { 
      "name" : "name 4", 
      "works" : [ 
       { 
        "code" : "A112", 
        "name" : "Nombre", 
        "price" : "11,2" 
       } 
      ] 
     }, 
     { 
      "name" : "Bombillos" 
     }, 
     { 
      "name" : "Pompas" 
     }, 
     { 
      "name" : "Bombillos 2" 
     }, 
     { 
      "name" : "Other type" 
     }, 
     { 
      "name" : "Other new type" 
     } 
    ] 
} 

regex न क्षेत्र परिणाम ठीक ..

+1

'regexQuery' क्या है? – Robin

+0

रेगेक्स के लिए मूल्य वाला एक स्ट्रिंग, मैंने अपने कोड को नोडजेस क्लाइंट से कॉपी किया है, मैं अपना questio संपादित करूंगा। Thanls – colymore

+0

मुझे लगता है कि समस्याओं में से एक यह है कि स्थितित्मक ऑपरेटर '$' एक प्रक्षेपण/अद्यतन ऑपरेटर है, एक क्वेरी ऑपरेटर नहीं है, 'worktypes.works.name' के बजाय कुछ "worktypes.works.name" 'के करीब आज़माएं। $ .name "' – Sammaye

उत्तर

4

आप नियमित अभिव्यक्ति के लिए एक जावास्क्रिप्ट देशी RegExp वस्तु का उपयोग कर रहे, मोंगो नियमित अभिव्यक्ति यह के भाग के रूप भेजे जाने की आवश्यकता पर कार्रवाई करने के लिए तथापि क्वेरी दस्तावेज़, और यह वही बात नहीं है।

इसके अलावा रेगेक्स आपके इच्छित मानों से मेल नहीं खाएगा। सटीक मिलान के लिए यह वास्तव में ^A0111$ हो सकता है, लेकिन आपका केस असंवेदनशील मिलान किसी समस्या का कारण बनता है जिससे संभावित सूचकांक का बड़ा स्कैन होता है। तो इसे लिखने का एक बेहतर तरीका है। असंवेदनशील मैचों के साथ समस्याओं के लिए प्रलेखन लिंक भी देखें।

बजाय $regex ऑपरेटर का उपयोग करें: एक प्रश्न के लिए

db.categories.find({ 
    "$and": [ 
     {"company":"New Company"}, 
     { "$or": [ 
      { "worktypes.works.name": { "$regex": "^A00011$|^a00011$" }}, 
      { "worktypes.works.code": { "$regex": "^A00011$|^a00011$" }} 
     ]} 
    ] 
}) 

इसके अलावा स्थितीय $ प्लेसहोल्डर मान्य नहीं हैं, वे केवल प्रक्षेपण या एक अद्यतन या पहले मिलान तत्व क्वेरी द्वारा पाया में किया जाता है।

लेकिन आपकी वास्तविक समस्या यह प्रतीत होती है कि आप केवल उन सरणी के तत्व प्राप्त करने का प्रयास कर रहे हैं जो आपकी शर्तों से मेल खाते हैं। आप .find() साथ ऐसा नहीं कर सकते और उस के लिए आप के बजाय .aggregate() उपयोग करने की आवश्यकता:

db.categories.aggregate([ 

    // Always makes sense to match the actual documents 
    { "$match": { 
     "$and": [ 
      {"company":"New Company"}, 
      { "$or": [ 
       { "worktypes.works.name": { "$regex": "^A00011$|^a00011$" }}, 
       { "worktypes.works.code": { "$regex": "^A00011$|^a00011$" }} 
      ]} 
     ] 
    }}, 

    // Unwind the worktypes array 
    { "$unwind": "$worktypes" }, 

    // Unwind the works array 
    { "$unwind": "$worktypes.works" }, 

    // Then use match to filter only the matching entries 
    { "$match": { 
     "$or": [ 
      { "worktypes.works.name": { "$regex": "^A00011$|^a00011$" } }, 
      { "worktypes.works.code": { "$regex": "^A00011$|^a00011$" } } 
     ] 
    }}, 

    /* Stop */ 
    // If you "really" need the arrays back then include all the following 
    // Otherwise the steps up to here actually got you your results 

    // First put the "works" array back together 
    { "$group": { 
     "_id": { 
      "_id": "$_id", 
      "company": "$company", 
      "workname": "$worktypes.name" 
     }, 
     "works": { "$push": "$worktypes.works" } 
    }}, 

    // Then put the "worktypes" array back 
    { "$group": { 
     "_id": "$_id._id", 
     "company": { "$first": "$_id.company" }, 
     "worktypes": { 
      "$push": { 
       "name": "$_id.workname", 
       "works": "$works" 
      } 
     } 
    }} 
]) 

तो क्या .aggregate() है यह सामान्य दस्तावेज़ के रूप में सरणी तत्वों टूट जाता है तो वे का उपयोग कर फ़िल्टर किया जा सकता इन चरणों के सभी के साथ करता है $match ऑपरेटर। इस तरह, केवल "तत्व" तत्व लौटाए जाते हैं।

क्या "ढूंढें" सही ढंग से कर रहा है "दस्तावेज़" से मेल खाता है जो शर्तों को पूरा करता है। चूंकि दस्तावेज़ों में वे तत्व होते हैं जो मेल खाते हैं तो वे वापस आते हैं। दो सिद्धांत बहुत अलग चीजें हैं।

जब आप कुल "फ़िल्टर" का उपयोग करना चाहते हैं।

+0

मैं अपना प्रश्न संपादित करता हूं, परिणाम नहीं हैं मुझे उम्मीद है .. – colymore

+0

@colymore वैसे परिणाम में दस्तावेज़ वास्तव में उन तत्वों को शामिल करता है जो अभिव्यक्ति से मेल खाते हैं। तो क्या आप वास्तव में कोशिश कर रहे हैं जी को केवल मैचों को वापस करने के लिए सरणी के परिणामों को "फिल्टर" करने के लिए? यह एक अलग बात है। –

+0

मैं केवल कार्यप्रणाली प्राप्त करने की कोशिश कर रहा हूं। कार्य करता है कि उसका worktype.work.code या नाम regex अभिव्यक्ति से मेल खाता है, और worktypes.works को त्यागें .. – colymore

1

मुझे लगता है कि वहाँ है एक टाइपो:

regex होना चाहिए: ^A00011.*$

ट्रिपल 0 के बजाय डबल 0

+0

को पुन: समूहित करना होगा, नतीजतन। मैंने अधिकांश कोड और नामों के साथ प्रयास किया है लेकिन कोई काम नहीं है। – colymore