sql >> Database teknologi >  >> NoSQL >> MongoDB

Spring Boot Data og MongoDB - Filter Subdocument Array Query

Tja, i Spring Data er den slags forespørgsler ikke trivial .

Dårlige nyheder:
Spring Data Repository har ikke en løsning til MongoDB Aggregation . Så du kan ikke implementere i MongoRepository nogen metode til at gøre det, såsom aggregateBy...

Gode nyheder:
Forårsdata giver MongoTemplate klasse, som giver dig mulighed for at udføre komplekse forespørgsler, som du ville gøre i standard MongoDB shell.

Så da du bare vil exclude underdokument, der ikke matcher en eller anden betingelse, skal vi definere de samlede pipelines .

Jeg går ud fra:

zip codes are Numeric (In your example is string)
And, to exclude subdocument, we filter by `zip`
There is no any other filter

MongoDB-sammenlægning ville være:

db.person.aggregate([
    {$unwind: "$address"},
    {$match: {"address.zip": 12345}},
    {$group: { _id: { "firstName":"$firstName", "lastName":"$lastName", _id:"$_id" }, address: { $push: "$address" } } },
    {$project: {_id:0, "firstName":"$_id.firstName", "lastName":"$_id.lastName", "address": "$address"}}
])

Hvis alle filtre lykkes, fik vi:

[ 
    {
        "address" : [ 
            {
                "zip" : 12345
            }, 
            {
                "zip" : 12345
            }
        ],
        "firstName" : "George",
        "lastName" : "Washington"
    }
]

Nu, på Spring Data måde, skal du tilføje nogle ændringer i dit projekt:

Find først din mongo-config.xml hvor du skal tilføje:

<!-- Define the mongoDbFactory with your database Name  -->
<mongo:db-factory uri="mongodb://user:[email protected]:27017/db"/>

<!-- Define the MongoTemplate  -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>

MongoTemplate er den centrale klasse af forårets MongoDB-understøttelse, der giver funktionssæt til at interagere med databasen. Skabelonen ... giver en kortlægning mellem dine domæneobjekter og MongoDB-dokumenter . Flere oplysninger

For det andet i din @Service klasse, tilføje følgende kode, der skal indlæses i @PostConstruct

@Autowired
private MongoOperations mongoOperations;

...

public List<Person> findByAddressZipCode(int zip) {

    List<AggregationOperation> list = new ArrayList<AggregationOperation>();
    list.add(Aggregation.unwind("address"));
    list.add(Aggregation.match(Criteria.where("address.zip").is(zip)));
    list.add(Aggregation.group("firstName", "lastName").push("address").as("address"));
    list.add(Aggregation.project("firstName", "lastName", "address"));
    TypedAggregation<Person> agg = Aggregation.newAggregation(Person.class, list);
    return mongoOperations.aggregate(agg, Person.class, Person.class).getMappedResults();
}

Bemærk: Begge, Person og Address skal have en tomme standardkonstruktør!




  1. Kan ikke instansiere mongoose-skema:Objekt er ikke en funktion

  2. Tilføjelse af nye værdier til eksisterende mongo-array

  3. Konverter ObjectID til String i mongo Aggregation

  4. Hvordan opretter man en CUPS-tjeneste til mongoDB?