MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

स्प्रिंग डेटा MongoDB में प्रश्नों के लिए एक गाइड

1. अवलोकन

यह ट्यूटोरियल विभिन्न स्प्रिंग डेटा MongoDB में क्वेरी के प्रकार के निर्माण पर ध्यान केंद्रित करेगा ।

हम क्वेरी . के साथ क्वेरी दस्तावेज़ों को देखने जा रहे हैं और मानदंड क्लासेस, ऑटो-जेनरेटेड क्वेरी मेथड्स, JSON क्वेरीज़, और QueryDSL।

मावेन सेटअप के लिए, हमारे परिचयात्मक लेख पर एक नज़र डालें।

2. दस्तावेज़ क्वेरी

स्प्रिंग डेटा के साथ MongoDB को क्वेरी करने के अधिक सामान्य तरीकों में से एक है क्वेरी . का उपयोग करना और मानदंड कक्षाएं, जो मूल संचालकों को बहुत बारीकी से प्रतिबिम्बित करती हैं।

2.1. है

यह समानता का उपयोग करने वाला एक मानदंड मात्र है। आइए देखें कि यह कैसे काम करता है।

निम्नलिखित उदाहरण में, हम एरिक . नाम के उपयोगकर्ताओं की तलाश करेंगे ।

आइए हमारे डेटाबेस को देखें:

[
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581907"),
        "_class" : "org.baeldung.model.User",
        "name" : "Eric",
        "age" : 45
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581908"),
        "_class" : "org.baeldung.model.User",
        "name" : "Antony",
        "age" : 55
    }
}

आइए अब क्वेरी कोड देखें:

Query query = new Query();
query.addCriteria(Criteria.where("name").is("Eric"));
List<User> users = mongoTemplate.find(query, User.class);

जैसा अपेक्षित था, यह तर्क वापस आता है:

{
    "_id" : ObjectId("55c0e5e5511f0a164a581907"),
    "_class" : "org.baeldung.model.User",
    "name" : "Eric",
    "age" : 45
}

2.2. रेगेक्स

एक अधिक लचीली और शक्तिशाली प्रकार की क्वेरी रेगेक्स है। यह MongoDB $regex . का उपयोग करके एक मानदंड बनाता है जो इस क्षेत्र के लिए रेगेक्स के लिए उपयुक्त सभी रिकॉर्ड लौटाता है।

यह startingWith . के समान कार्य करता है और समाप्त होना संचालन।

इस उदाहरण में, हम उन सभी उपयोगकर्ताओं की तलाश करेंगे जिनके नाम A . से शुरू होते हैं ।

यहाँ डेटाबेस की स्थिति है:

[
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581907"),
        "_class" : "org.baeldung.model.User",
        "name" : "Eric",
        "age" : 45
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581908"),
        "_class" : "org.baeldung.model.User",
        "name" : "Antony",
        "age" : 33
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581909"),
        "_class" : "org.baeldung.model.User",
        "name" : "Alice",
        "age" : 35
    }
]

अब क्वेरी बनाते हैं:

Query query = new Query();
query.addCriteria(Criteria.where("name").regex("^A"));
List<User> users = mongoTemplate.find(query,User.class);

यह चलता है और 2 रिकॉर्ड लौटाता है:

[
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581908"),
        "_class" : "org.baeldung.model.User",
        "name" : "Antony",
        "age" : 33
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581909"),
        "_class" : "org.baeldung.model.User",
        "name" : "Alice",
        "age" : 35
    }
]

यहां एक और त्वरित उदाहरण दिया गया है, इस बार उन सभी उपयोगकर्ताओं की तलाश की जा रही है जिनके नाम c . से समाप्त होते हैं :

Query query = new Query();
query.addCriteria(Criteria.where("name").regex("c$"));
List<User> users = mongoTemplate.find(query, User.class);

तो परिणाम होगा:

{
    "_id" : ObjectId("55c0e5e5511f0a164a581907"),
    "_class" : "org.baeldung.model.User",
    "name" : "Eric",
    "age" : 45
}

2.3. लेफ्टिनेंट और gt

ये ऑपरेटर $lt . का उपयोग करके एक मानदंड बनाते हैं (इससे कम) और $gt (से अधिक) ऑपरेटर।

आइए एक त्वरित उदाहरण लेते हैं जहां हम 20 से 50 वर्ष की आयु के बीच के सभी उपयोगकर्ताओं की तलाश कर रहे हैं।

डेटाबेस है:

[
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581907"),
        "_class" : "org.baeldung.model.User",
        "name" : "Eric",
        "age" : 45
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581908"),
        "_class" : "org.baeldung.model.User",
        "name" : "Antony",
        "age" : 55
    }
}

क्वेरी कोड:

Query query = new Query();
query.addCriteria(Criteria.where("age").lt(50).gt(20));
List<User> users = mongoTemplate.find(query,User.class);

और 20 से अधिक और 50 से कम आयु वाले सभी उपयोगकर्ताओं के लिए परिणाम:

{
    "_id" : ObjectId("55c0e5e5511f0a164a581907"),
    "_class" : "org.baeldung.model.User",
    "name" : "Eric",
    "age" : 45
}

2.4. क्रमबद्ध करें

क्रमबद्ध करें परिणामों के लिए सॉर्ट क्रम निर्दिष्ट करने के लिए उपयोग किया जाता है।

नीचे दिया गया उदाहरण सभी उपयोगकर्ताओं को आयु के अनुसार बढ़ते क्रम में लौटाता है।

सबसे पहले, यहां मौजूदा डेटा है:

[
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581907"),
        "_class" : "org.baeldung.model.User",
        "name" : "Eric",
        "age" : 45
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581908"),
        "_class" : "org.baeldung.model.User",
        "name" : "Antony",
        "age" : 33
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581909"),
        "_class" : "org.baeldung.model.User",
        "name" : "Alice",
        "age" : 35
    }
]

क्रमबद्ध करें . क्रियान्वित करने के बाद :

Query query = new Query();
query.with(Sort.by(Sort.Direction.ASC, "age"));
List<User> users = mongoTemplate.find(query,User.class);

और यहाँ क्वेरी का परिणाम है, जिसे उम्र . द्वारा अच्छी तरह से क्रमबद्ध किया गया है :

[
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581908"),
        "_class" : "org.baeldung.model.User",
        "name" : "Antony",
        "age" : 33
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581909"),
        "_class" : "org.baeldung.model.User",
        "name" : "Alice",
        "age" : 35
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581907"),
        "_class" : "org.baeldung.model.User",
        "name" : "Eric",
        "age" : 45
    }
]

2.5. पेजेबल

आइए पेजिनेशन का उपयोग करके एक त्वरित उदाहरण देखें।

यहाँ डेटाबेस की स्थिति है:

[
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581907"),
        "_class" : "org.baeldung.model.User",
        "name" : "Eric",
        "age" : 45
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581908"),
        "_class" : "org.baeldung.model.User",
        "name" : "Antony",
        "age" : 33
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581909"),
        "_class" : "org.baeldung.model.User",
        "name" : "Alice",
        "age" : 35
    }
]

अब यहाँ क्वेरी लॉजिक है, बस आकार 2 के पृष्ठ के लिए पूछ रहा है:

final Pageable pageableRequest = PageRequest.of(0, 2);
Query query = new Query();
query.with(pageableRequest);

और परिणाम, अपेक्षित के रूप में 2 दस्तावेज़:

[
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581907"),
        "_class" : "org.baeldung.model.User",
        "name" : "Eric",
        "age" : 45
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581908"),
        "_class" : "org.baeldung.model.User",
        "name" : "Antony",
        "age" : 33
    }
]

3. जेनरेट की गई क्वेरी विधियाँ

अब आइए अधिक सामान्य प्रकार की क्वेरी का अन्वेषण करें जो स्प्रिंग डेटा आमतौर पर प्रदान करता है, ऑटो-जेनरेटेड क्वेरी जो विधि नामों से बाहर होती हैं।

इस प्रकार के प्रश्नों का लाभ उठाने के लिए केवल एक चीज जो हमें करने की आवश्यकता है, वह है रिपोजिटरी इंटरफ़ेस पर विधि घोषित करना:

public interface UserRepository 
  extends MongoRepository<User, String>, QueryDslPredicateExecutor<User> {
    ...
}

3.1. FindByX

हम क्वेरी के प्रकार की खोज करके सरल शुरुआत करेंगे। इस मामले में, हम नाम से खोज का उपयोग करेंगे:

List<User> findByName(String name);

पिछले अनुभाग की तरह, 2.1, दिए गए नाम के साथ सभी उपयोगकर्ताओं को ढूंढते हुए, क्वेरी के समान परिणाम होंगे:

List<User> users = userRepository.findByName("Eric");

3.2. शुरूआत और समाप्त होना

खंड 2.2 में, हमने एक रेगेक्स . की खोज की आधारित क्वेरी। शुरुआत और अंत निश्चित रूप से कम शक्तिशाली हैं, लेकिन फिर भी काफी उपयोगी हैं, खासकर अगर हमें वास्तव में उन्हें लागू करने की आवश्यकता नहीं है।

यहां एक त्वरित उदाहरण दिया गया है कि संचालन कैसा दिखेगा:

List<User> findByNameStartingWith(String regexp);
List<User> findByNameEndingWith(String regexp);

वास्तव में इसका उपयोग करने का उदाहरण, निश्चित रूप से बहुत सरल होगा:

List<User> users = userRepository.findByNameStartingWith("A");
List<User> users = userRepository.findByNameEndingWith("c");

और परिणाम बिल्कुल वही हैं।

3.3. बीच

अनुभाग 2.3 के समान, यह ageGT . के बीच आयु वाले सभी उपयोगकर्ताओं को लौटाएगा और आयुएलटी:

List<User> findByAgeBetween(int ageGT, int ageLT);

विधि को कॉल करने के परिणामस्वरूप बिल्कुल वही दस्तावेज़ मिलेंगे:

List<User> users = userRepository.findByAgeBetween(20, 50);

3.4. पसंद करें और आदेश द्वारा

आइए इस बार एक अधिक उन्नत उदाहरण पर एक नज़र डालते हैं, जेनरेट की गई क्वेरी के लिए दो प्रकार के संशोधक का संयोजन।

हम उन सभी उपयोगकर्ताओं की तलाश करने जा रहे हैं जिनके नाम A, . अक्षर वाले हैं और हम आयु के अनुसार परिणामों को आरोही क्रम में भी क्रमित करने जा रहे हैं:

List<User> users = userRepository.findByNameLikeOrderByAgeAsc("A");

डेटाबेस के लिए हमने खंड 2.4 में उपयोग किया, परिणाम होगा:

[
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581908"),
        "_class" : "org.baeldung.model.User",
        "name" : "Antony",
        "age" : 33
    },
    {
        "_id" : ObjectId("55c0e5e5511f0a164a581909"),
        "_class" : "org.baeldung.model.User",
        "name" : "Alice",
        "age" : 35
    }
]

4. JSON क्वेरी विधियाँ

यदि हम किसी विधि नाम या मानदंड की सहायता से किसी क्वेरी का प्रतिनिधित्व नहीं कर सकते हैं, तो हम कुछ और निम्न स्तर पर कर सकते हैं, @Query का उपयोग करें एनोटेशन

इस एनोटेशन के साथ, हम एक कच्ची क्वेरी को Mongo JSON क्वेरी स्ट्रिंग के रूप में निर्दिष्ट कर सकते हैं।

4.1. ढूंढें

आइए सरल शुरुआत करें और देखें कि हम एक इसके द्वारा खोजें . का प्रतिनिधित्व कैसे करेंगे विधि का प्रकार पहला:

@Query("{ 'name' : ?0 }")
List<User> findUsersByName(String name);

इस विधि को उपयोगकर्ताओं को नाम से वापस करना चाहिए। प्लेसहोल्डर ?0 विधि के पहले पैरामीटर का संदर्भ देता है।

List<User> users = userRepository.findUsersByName("Eric");

4.2. $regex

हम रेगेक्स संचालित क्वेरी . को भी देख सकते हैं जो निश्चित रूप से अनुभाग 2.2 और 3.2 के समान परिणाम देता है:

@Query("{ 'name' : { $regex: ?0 } }")
List<User> findUsersByRegexpName(String regexp);

उपयोग भी बिल्कुल वैसा ही है:

List<User> users = userRepository.findUsersByRegexpName("^A");
List<User> users = userRepository.findUsersByRegexpName("c$");

4.3. $lt और $gt

आइए अब लेफ्टिनेंट और gt . को लागू करें क्वेरी:

@Query("{ 'age' : { $gt: ?0, $lt: ?1 } }")
List<User> findUsersByAgeBetween(int ageGT, int ageLT);

अब जबकि इस विधि में 2 पैरामीटर हैं, हम इनमें से प्रत्येक को रॉ क्वेरी में इंडेक्स द्वारा संदर्भित कर रहे हैं, ?0 और ?1:

List<User> users = userRepository.findUsersByAgeBetween(20, 50);

5. QueryDSL क्वेरीज़

मोंगो रिपोजिटरी QueryDSL प्रोजेक्ट के लिए अच्छा समर्थन है, इसलिए हम यहां भी उस अच्छे, टाइप-सुरक्षित API का लाभ उठा सकते हैं।

5.1. मावेन निर्भरता

सबसे पहले, सुनिश्चित करें कि हमारे पास पोम में परिभाषित सही मावेन निर्भरताएं हैं:

<dependency>
    <groupId>com.mysema.querydsl</groupId>
    <artifactId>querydsl-mongodb</artifactId>
    <version>4.3.1</version>
</dependency>
<dependency>
    <groupId>com.mysema.querydsl</groupId>
    <artifactId>querydsl-apt</artifactId>
    <version>4.3.1</version>
</dependency>

5.2. प्रश्न -कक्षाएं

QueryDSL ने प्रश्न बनाने के लिए Q-वर्गों का उपयोग किया, लेकिन चूंकि हम वास्तव में इन्हें हाथ से नहीं बनाना चाहते, हमें इन्हें उत्पन्न करने की आवश्यकता है किसी तरह।

हम ऐसा करने के लिए apt-maven-plugin का उपयोग करने जा रहे हैं:

<plugin>    
    <groupId>com.mysema.maven</groupId>
    <artifactId>apt-maven-plugin</artifactId>
    <version>1.1.3</version>
    <executions>
        <execution>
            <goals>
                <goal>process</goal>
            </goals>
            <configuration>
                <outputDirectory>target/generated-sources/java</outputDirectory>
                <processor>
                  org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor
                </processor>
            </configuration>
        </execution>
     </executions>
</plugin>

आइए देखें उपयोगकर्ता वर्ग, विशेष रूप से @QueryEntity . पर ध्यान केंद्रित करते हुए एनोटेशन:

@QueryEntity 
@Document
public class User {
 
    @Id
    private String id;
    private String name;
    private Integer age;
 
    // standard getters and setters
}

प्रक्रिया चलाने के बाद मावेन जीवनचक्र का लक्ष्य (या उसके बाद कोई अन्य लक्ष्य), उपयुक्त प्लगइन नई कक्षाएं उत्पन्न करेगा target/generated-sources/java/{your package structure} . के अंतर्गत :

/**
 * QUser is a Querydsl query type for User
 */
@Generated("com.mysema.query.codegen.EntitySerializer")
public class QUser extends EntityPathBase<User> {

    private static final long serialVersionUID = ...;

    public static final QUser user = new QUser("user");

    public final NumberPath<Integer> age = createNumber("age", Integer.class);

    public final StringPath id = createString("id");

    public final StringPath name = createString("name");

    public QUser(String variable) {
        super(User.class, forVariable(variable));
    }

    public QUser(Path<? extends User> path) {
        super(path.getType(), path.getMetadata());
    }

    public QUser(PathMetadata<?> metadata) {
        super(User.class, metadata);
    }
}

यह इस वर्ग के कारण है कि हमें अपने प्रश्न बनाने की आवश्यकता नहीं है।

एक साइड नोट के रूप में, यदि हम एक्लिप्स का उपयोग कर रहे हैं, तो इस प्लगइन को पेश करने से पोम में निम्नलिखित चेतावनी उत्पन्न होगी:

मावेन इंस्टॉल ठीक काम करता है और QUser वर्ग उत्पन्न होता है, लेकिन पोम में एक प्लगइन हाइलाइट किया जाता है।

एक त्वरित समाधान JDK को eclipse.ini . में मैन्युअल रूप से इंगित करना है :

...
-vm
{path_to_jdk}\jdk{your_version}\bin\javaw.exe

5.3. नया भंडार

अब हमें वास्तव में अपने भंडारों में QueryDSL समर्थन को सक्षम करने की आवश्यकता है, जो कि केवल QueryDslPredicateExecutor का विस्तार करके किया जाता है। इंटरफ़ेस :

public interface UserRepository extends 
  MongoRepository<User, String>, QuerydslPredicateExecutor<User>

5.4. ईक

समर्थन सक्षम होने पर, आइए अब उन्हीं प्रश्नों को लागू करें जैसा कि हमने पहले सचित्र किया था।

हम साधारण समानता के साथ शुरुआत करेंगे:

QUser qUser = new QUser("user");
Predicate predicate = qUser.name.eq("Eric");
List<User> users = (List<User>) userRepository.findAll(predicate);

5.5. शुरूआत और समाप्ति

इसी तरह, आइए पिछली क्वेरी को लागू करें और उन उपयोगकर्ताओं को खोजें जिनका नाम A . से शुरू हो रहा है :

QUser qUser = new QUser("user");
Predicate predicate = qUser.name.startsWith("A");
List<User> users = (List<User>) userRepository.findAll(predicate);

साथ ही c . के साथ समाप्त होता है :

QUser qUser = new QUser("user");
Predicate predicate = qUser.name.endsWith("c");
List<User> users = (List<User>) userRepository.findAll(predicate);

परिणाम अनुभाग 2.2, 3.2 और 4.2 जैसा ही है।

5.6. बीच

अगली क्वेरी पिछले अनुभागों की तरह 20 से 50 वर्ष की आयु वाले उपयोगकर्ताओं को लौटाएगी:

QUser qUser = new QUser("user");
Predicate predicate = qUser.age.between(20, 50);
List<User> users = (List<User>) userRepository.findAll(predicate);

  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. 'MongoDB 3.0 में सॉकेट फ़ाइल त्रुटि को अनलिंक करने में विफल'

  2. नेवला वस्तुओं के नेस्टेड सरणी में अद्वितीय मान

  3. MongoDB नेस्टेड सरणी क्वेरी

  4. अपने क्लाउड डेटाबेस को प्रबंधित करने के लिए AWS पर ClusterControl को कैसे परिनियोजित करें

  5. ग्राफ़ डीबी बनाम दस्तावेज़ डीबी बनाम ट्रिपलस्टोर्स