2013-07-29 7 views
6

मैं एक POJO इस तरह एनोटेट है का उपयोग कर नजरअंदाज कर दिया:@Indexed एनोटेशन जब नाम वाले संग्रह

@Document 
class Car { 

    @Id 
    String id ; 

    @Indexed 
    String manufacturer ; 

} 

और मैं MongoTemplate उपयोग कर रहा हूँ मोंगो में डालने के लिए। अगर मैं संग्रह नाम निर्दिष्ट किए बिना सम्मिलित करता हूं, तो सब कुछ ठीक काम करता है। हालांकि, अगर मैं संग्रह नाम निर्दिष्ट करता हूं, तो _id एक को छोड़कर कोई भी अनुक्रमणिका बनाई गई नहीं है।

मैं वास्तव में क्योंकि संग्रह नाम मैन्युअल रूप से निर्दिष्ट करने के लिए सक्षम होना चाहिए:

  • मैं एक ही संग्रह में Car अंत तक की विभिन्न उपवर्गों सुनिश्चित करने की आवश्यकता
  • मैं के प्रत्येक वर्ष के मूल्य की दुकान चाहते हैं Cars एक अलग संग्रह में

क्या मुझे मैन्युअल रूप से ensureIndex() पर कॉल करना है? यदि हां, तो ऐसा करने का कोई तरीका है जो मेरे @Indexed एनोटेशन का उपयोग करता है? वास्तविक वस्तुओं मैं बचाने के लिए कोशिश कर रहा हूँ एक बहुत अधिक 'कार'

+0

इसी प्रकार के प्रश्न http सूचकांक बनाने के लिए इस्तेमाल किया जा सकता है://stackoverflow.com/questions/23942469/create-index-in-correct-collection – Alex

उत्तर

4

दुर्भाग्य MongoTemplate समारोह

public void insert(Object objectToSave, String collectionName) 

केवल वस्तु को बचाने के लिए और किसी भी टिप्पणी किए गए अनुक्रमणिका बनाने के लिए collectionName का उपयोग करने से जटिल हैं। यदि ऑपरेशन को सहेजने के लिए ऑब्जेक्ट पास किया गया है तो एप्लिकेशन इवेंट श्रोता MongoPersistentEntityIndexCreator@Indexed एनोटेशन के लिए सहेजी गई इकाई वर्ग स्कैन करें और अनुक्रमणिका बनाएं। लेकिन यह (स्रोतों से) अगले सूत्र के आधार पर संग्रह नाम का पता लगाने:

String collection = StringUtils.hasText(index.collection()) ? index.collection() : entity.getCollection(); 

जहां index.collection()@Indexed एनोटेशन और entity.getCollection()@Document टिप्पणी से से संग्रह है।

तो, आपको मैन्युअल रूप से ensureIndex() पर कॉल करने की आवश्यकता है। यह अजीब व्यवहार है। मुझे लगता है कि तुम यहाँ बग खोल सकते हैं: DATAMONGO

संपादित करें: मुझे लगता है कि आप समारोह है कि @Document साथ एनोटेट सभी वर्गों लौट बना सकते हैं और भी MongoDB cars.<year> से शुरू से सभी संग्रह प्राप्त कर सकते हैं। फिर आप @Indexed के साथ एनोटेटेड सभी फ़ील्ड का विश्लेषण कर सकते हैं और परिणामस्वरूप, संग्रह सूची का उपयोग करके इस फ़ील्ड के लिए ensureIndex पर कॉल करें।

+0

@ डेव: –

1

मैं वास्तव में क्योंकि मैन्युअल संग्रह नाम निर्दिष्ट करने में सक्षम होना चाहिए:

@Document(collection="cars") 
class Car { 

    @Id 
    String id ; 

    @Indexed 
    String manufacturer ; 

} 

@Document(collection="cars") 
class Honda extends Car { 

} 

@Document(collection="cars") 
class Volvo extends Car { 

} 
:

I need to ensure different subclasses of Car end up in the same collection 
I would like to store each year's worth of Cars in a separate collection 

अपने पहले बयान का सवाल है, आप का उपयोग कर @Document मेटाडाटा एनोटेशन एक मात्र संग्रह लागू कर सकते हैं

@Document का संग्रह क्षेत्र सावधानी बरतता है कि कार के प्रत्येक उप-वर्ग कार संग्रह में और साथ ही इंडेक्स स्वचालित रूप से @Indexed एनोटेशन की सहायता से बनाया गया है।

+0

का उत्तर देने के लिए अतिरिक्त जोड़ा जा सकता है, जैसा कि आप कहते हैं, ठीक है, यह दूसरी बिंदु = ( – Dave

+0

मुझे आपका दूसरा बिंदु समझ में नहीं आया। कृपया एक उदाहरण दें –

+0

निश्चित बात। यह सुनिश्चित नहीं है कि इस उपयोग-मामले में कितना व्यापक है, लेकिन मेरे लिए यह मेरे प्रत्येक ग्राहक के लिए पूरी तरह से अलग संग्रह बनाए रखने के लिए बहुत समझ में आता है। वास्तविक वस्तु जो मैं संग्रहीत कर रहा हूं वह एक ट्वीट है (एक कार नहीं), और प्रत्येक ग्राहक के लिए मैं सैकड़ों हजारों ट्वीट्स इकट्ठा कर सकता हूं। प्रत्येक ट्वीट के लिए मैं प्रत्येक क्लाइंट के लिए अलग-अलग एनोटेशन संलग्न करूंगा। इसलिए, यदि वे सभी एक संग्रह में हैं, तो यह बहुत बड़ा हो सकता है, और मुझे इस बात का ट्रैक रखने के लिए बहुत से अतिरिक्त फ़ील्ड जोड़ना होगा कि किस क्लाइंट ने ट्वीट और एनोटेशन पर ध्यान दिया है। एक संग्रह = गन्दा, एकाधिक संग्रह = साफ। – Dave

0

शायद आप डीबी स्तर पर उतरने और जांच कर रहे हैं कि संग्रह में इंडेक्स हैं जो आपको getIndexes का उपयोग करने की आवश्यकता है और सुनिश्चित करें कि आपके एप्लिकेशन के हिस्से के रूप में सुनिश्चित करें इंडेक्स को शुरू करें।

युक्ति: कक्षा में प्रारंभिक बीन लागू करें जो आपके आवेदन के लिए मोंगो को कॉन्फ़िगर करता है और वहां जादू करता है।

कोई प्रचार नहीं, आईएमएचओ वसंत कुछ चीजों पर अच्छा है और इसी तरह दूसरों पर भी। मैं गैर एक्सए वातावरण में डी & TXN प्रबंधन के अलावा ब्लोट से बचने की कोशिश करता हूं।

0

एक लंबी खोज के बाद, मुझे लगता है कि अब एनोटेशन का उपयोग करके सकारात्मक नहीं है, इसलिए मैंने इस परिदृश्य को प्रबंधित करने के लिए प्रोग्रामेटिक तरीके से बनाया है।

सामान्य सूचकांक और मिश्रित सूचकांक

सबसे पहले मैं सूचकांक संरचना मैप करने के लिए एक वस्तु परिभाषित बनाने।

public class CollectionDefinition { 

private String id; 
private String collectionName; 
private LinkedHashMap<String, Sort.Direction> normalIndexMap; 
private ArrayList<String> compoundIndexMap; 

public String getId() { 
    return id; 
} 

public void setId(String id) { 
    this.id = id; 
} 

public String getCollectionName() { 
    return collectionName; 
} 

public void setCollectionName(String collectionName) { 
    this.collectionName = collectionName; 
} 

public LinkedHashMap<String, Sort.Direction> getNormalIndexMap() { 
    return normalIndexMap; 
} 

public void setNormalIndexMap(LinkedHashMap<String, Sort.Direction> normalIndexMap) { 
    this.normalIndexMap = normalIndexMap; 
} 

public ArrayList<String> getCompoundIndexMap() { 
    return compoundIndexMap; 
} 

public void setCompoundIndexMap(ArrayList<String> compoundIndexMap) { 
    this.compoundIndexMap = compoundIndexMap; 
} 

Json संग्रह इस

{ 
"collectionName" : "example", 
"normalIndexMap" : { 
    "sessionId" : "ASC", 
    "hash" : "DESC" 
}, 
"compoundIndexMap" : [ 
    "{\"hash\":1,\"sessionId\":1,\"serverDate\":-1}", 
    "{\"sessionId\":1,\"serverDate\":-1}", 
    "{\"sessionId\":1,\"loginWasSuccessful\":1,\"loginDate\":-1}" 
]} 

की तरह लग रहे तो फिर हम संग्रह और अनुक्रमित बना सकते हैं जाएगा

private List<IndexDefinition> createIndexList(Map<String, Sort.Direction> normalIndexMap) { 
    Set<String> keySet = normalIndexMap.keySet(); 
    List<IndexDefinition> indexArray = new ArrayList<>(); 
    for (String key : keySet) { 
     indexArray.add(new Index(key, normalIndexMap.get(key)).background()); 
    } 
    return indexArray; 
} 

उत्पन्न होने वाली एकल सूचकांक सूची एक क्षेत्र सूचकांक बनाने के लिए इस्तेमाल किया जा सकता है

private void createIndexes(List<IndexDefinition> indexDefinitionList, MongoOperations mongoOperations, String collectionName) { 
    indexDefinitionList.forEach(indexDefinition -> mongoOperations.indexOps(collectionName).ensureIndex(indexDefinition)); 
} 

यौगिक सूचकांक या multifield सूचकांक मुश्किल है, हम सूचकांक

private List<DBObject> createCompountIndexList(List<String> compoundIndexStringMapList) {//NOSONAR IS IN USE 
    if (compoundIndexStringMapList == null || compoundIndexStringMapList.isEmpty()) 
     return new ArrayList<>(); //NOSONAR 
    ObjectMapper mapper = new ObjectMapper(); 
    List<DBObject> basicDBObjectList = new ArrayList<>(); 
    for (String stringMapList : compoundIndexStringMapList) { 
     LinkedHashMap<String, Integer> parsedMap; 
     try { 
      parsedMap = mapper.readValue(stringMapList, new TypeReference<Map<String, Integer>>() { 
      }); 
      BasicDBObjectBuilder dbObjectBuilder = BasicDBObjectBuilder.start(); 
      Iterator it = parsedMap.entrySet().iterator(); 
      while (it.hasNext()) { 
       Map.Entry indexElement = (Map.Entry) it.next(); 
       dbObjectBuilder.add((String) indexElement.getKey(), indexElement.getValue()); 
       it.remove(); // avoids a ConcurrentModificationException 
      } 
      basicDBObjectList.add(dbObjectBuilder.get()); 
     } catch (IOException e) {//NOSONAR I´m logging it, we can not do anything more here cause it is part of the db configuration settings that need to be correct 
      Logger.getLogger(JsonCollectionCreation.class).error("The compound index definition " + stringMapList + " is not correct it can not be mapped to LinkHashMap"); 
     } 

    } 
    return basicDBObjectList; 
} 

परिभाषित करने के लिए DBObjects बनाने की जरूरत और परिणाम संग्रह में

private void createCompoundIndex(List<DBObject> compoundIndexList, MongoOperations mongoOperations, String collectionName) { 
    if (compoundIndexList.isEmpty()) return; 
    for (DBObject compoundIndexDefinition : compoundIndexList) { 
     mongoOperations.indexOps(collectionName).ensureIndex(new CompoundIndexDefinition(compoundIndexDefinition).background()); 
    } 
} 
संबंधित मुद्दे