यह लेख एक श्रृंखला का हिस्सा है:• इलास्टिक्स खोज के साथ एक सरल टैगिंग कार्यान्वयन
• जेपीए के साथ एक सरल टैगिंग कार्यान्वयन
• जेपीए के साथ एक उन्नत टैगिंग कार्यान्वयन
• MongoDB के साथ एक सरल टैगिंग कार्यान्वयन (वर्तमान लेख)
1. अवलोकन
इस ट्यूटोरियल में, हम Java और MongoDB का उपयोग करके एक सरल टैगिंग कार्यान्वयन पर एक नज़र डालेंगे।
अवधारणा से अपरिचित लोगों के लिए, एक टैग एक ऐसा कीवर्ड है जिसका उपयोग दस्तावेज़ों को विभिन्न श्रेणियों में समूहित करने के लिए "लेबल" के रूप में किया जाता है। यह उपयोगकर्ताओं को समान सामग्री के माध्यम से जल्दी से नेविगेट करने की अनुमति देता है और बड़ी मात्रा में डेटा के साथ काम करते समय यह विशेष रूप से उपयोगी होता है।
कहा जा रहा है, यह आश्चर्य की बात नहीं है कि इस तकनीक का उपयोग आमतौर पर ब्लॉगों में किया जाता है। इस परिदृश्य में, प्रत्येक पोस्ट में शामिल किए गए विषयों के अनुसार एक या अधिक टैग होते हैं। जब उपयोगकर्ता पढ़ना समाप्त कर लेता है, तो वह उस विषय से संबंधित अधिक सामग्री देखने के लिए किसी एक टैग का अनुसरण कर सकता है।
आइए देखें कि हम इस परिदृश्य को कैसे लागू कर सकते हैं।
2. निर्भरता
डेटाबेस को क्वेरी करने के लिए, हमें अपने pom.xml में MongoDB ड्राइवर निर्भरता को शामिल करना होगा :
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.6.3</version>
</dependency>
इस निर्भरता का वर्तमान संस्करण यहां पाया जा सकता है।
3. डेटा मॉडल
सबसे पहले, आइए यह योजना बनाकर शुरू करें कि पोस्ट दस्तावेज़ कैसा दिखना चाहिए।
इसे सरल रखने के लिए, हमारे डेटा मॉडल में केवल एक शीर्षक होगा, जिसका उपयोग हम दस्तावेज़ आईडी, एक लेखक और कुछ टैग के रूप में भी करेंगे।
हम टैग को एक सरणी के अंदर संग्रहीत करेंगे क्योंकि एक पोस्ट में शायद केवल एक से अधिक होंगे:
{
"_id" : "Java 8 and MongoDB",
"author" : "Donato Rimenti",
"tags" : ["Java", "MongoDB", "Java 8", "Stream API"]
}
हम संबंधित जावा मॉडल वर्ग भी बनाएंगे:
public class Post {
private String title;
private String author;
private List<String> tags;
// getters and setters
}
4. टैग अपडेट करना
अब जब हमने डेटाबेस सेट कर लिया है और कुछ नमूना पोस्ट डाल दिए हैं, तो देखते हैं कि हम उन्हें कैसे अपडेट कर सकते हैं।
हमारी रिपॉजिटरी क्लास में टैग जोड़ने और हटाने के दो तरीके शामिल होंगे उन्हें खोजने के लिए शीर्षक का उपयोग करके। हम यह इंगित करने के लिए एक बूलियन भी लौटाएंगे कि क्वेरी ने किसी तत्व को अपडेट किया है या नहीं:
public boolean addTags(String title, List<String> tags) {
UpdateResult result = collection.updateOne(
new BasicDBObject(DBCollection.ID_FIELD_NAME, title),
Updates.addEachToSet(TAGS_FIELD, tags));
return result.getModifiedCount() == 1;
}
public boolean removeTags(String title, List<String> tags) {
UpdateResult result = collection.updateOne(
new BasicDBObject(DBCollection.ID_FIELD_NAME, title),
Updates.pullAll(TAGS_FIELD, tags));
return result.getModifiedCount() == 1;
}
हमने addEachToSet . का उपयोग किया पुश . के बजाय विधि जोड़ने के लिए ताकि अगर टैग पहले से मौजूद हैं, तो हम उन्हें दोबारा नहीं जोड़ेंगे।
यह भी ध्यान दें कि addToSet ऑपरेटर या तो काम नहीं करेगा क्योंकि यह नए टैग को नेस्टेड सरणी के रूप में जोड़ देगा जो कि हम नहीं चाहते हैं।
एक और तरीका है जिससे हम अपने अपडेट को निष्पादित कर सकते हैं, वह है मोंगो शेल के माध्यम से। उदाहरण के लिए, चलिए JUnit5 को Java के साथ अपडेट करते हैं। विशेष रूप से, हम टैग जोड़ना चाहते हैं जावा और जम्मूइकाई5 और टैग हटा दें वसंत और बाकी :
db.posts.updateOne(
{ _id : "JUnit 5 with Java" },
{ $addToSet :
{ "tags" :
{ $each : ["Java", "JUnit5"] }
}
});
db.posts.updateOne(
{_id : "JUnit 5 with Java" },
{ $pull :
{ "tags" : { $in : ["Spring", "REST"] }
}
});
5. प्रश्न
अंत में, आइए कुछ सबसे सामान्य प्रश्नों के बारे में जानें, जिनमें टैग के साथ काम करते समय हमारी रुचि हो सकती है। इस उद्देश्य के लिए, हम विशेष रूप से तीन सरणी ऑपरेटरों का लाभ उठाएंगे:
- $in – उन दस्तावेज़ों को लौटाता है जहाँ किसी फ़ील्ड में कोई मान होता है निर्दिष्ट सरणी के
- $nin – उन दस्तावेज़ों को लौटाता है जहाँ किसी फ़ील्ड में कोई मान नहीं होता निर्दिष्ट सरणी के
- $सभी – उन दस्तावेज़ों को लौटाता है जहाँ एक फ़ील्ड में सभी मान होते हैं निर्दिष्ट सरणी के
हम तर्क के रूप में पारित टैग के संग्रह के संबंध में पोस्ट को क्वेरी करने के लिए तीन विधियों को परिभाषित करेंगे . वे उन पोस्टों को वापस कर देंगे जो कम से कम एक टैग से मेल खाते हैं, सभी टैग और कोई भी टैग नहीं। हम Java 8 के Stream API का उपयोग करके किसी दस्तावेज़ और हमारे मॉडल के बीच रूपांतरण को संभालने के लिए एक मैपिंग विधि भी बनाएंगे:
public List<Post> postsWithAtLeastOneTag(String... tags) {
FindIterable<Document> results = collection
.find(Filters.in(TAGS_FIELD, tags));
return StreamSupport.stream(results.spliterator(), false)
.map(TagRepository::documentToPost)
.collect(Collectors.toList());
}
public List<Post> postsWithAllTags(String... tags) {
FindIterable<Document> results = collection
.find(Filters.all(TAGS_FIELD, tags));
return StreamSupport.stream(results.spliterator(), false)
.map(TagRepository::documentToPost)
.collect(Collectors.toList());
}
public List<Post> postsWithoutTags(String... tags) {
FindIterable<Document> results = collection
.find(Filters.nin(TAGS_FIELD, tags));
return StreamSupport.stream(results.spliterator(), false)
.map(TagRepository::documentToPost)
.collect(Collectors.toList());
}
private static Post documentToPost(Document document) {
Post post = new Post();
post.setTitle(document.getString(DBCollection.ID_FIELD_NAME));
post.setAuthor(document.getString("author"));
post.setTags((List<String>) document.get(TAGS_FIELD));
return post;
}
फिर से, आइए शेल समकक्ष प्रश्नों पर भी एक नज़र डालते हैं . हम क्रमशः MongoDB . के साथ टैग किए गए तीन अलग-अलग पोस्ट संग्रह प्राप्त करेंगे या स्ट्रीम एपीआई, दोनों के साथ टैग किया गया जावा 8 और जुनीट 5 और ग्रूवी . के साथ टैग नहीं किया गया न ही स्कैला :
db.posts.find({
"tags" : { $in : ["MongoDB", "Stream API" ] }
});
db.posts.find({
"tags" : { $all : ["Java 8", "JUnit 5" ] }
});
db.posts.find({
"tags" : { $nin : ["Groovy", "Scala" ] }
});