sql >> Databáze >  >> NoSQL >> MongoDB

Spring Boot Data a MongoDB - Filtrování dotazu pole subdokumentu

No, v Spring Data takový druh dotazů není trivial .

Špatné zprávy:
Spring Data Repository nemá řešení pro MongoDB Aggregation . V MongoRepository tedy nemůžete implementovat žádnou metodu, jak to udělat, například aggregateBy...

Dobrá zpráva:
Spring Data poskytuje MongoTemplate třída, která vám umožňuje provádět složité dotazy, jako byste to dělali ve standardním prostředí MongoDB.

Takže, jak jen chcete exclude vnořený dokument, který neodpovídá nějaké podmínce, musíme definovat agregované pipelines .

Předpokládám:

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

Agregace MongoDB by byla:

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"}}
])

Pokud jsou všechny filtry úspěšné, máme:

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

Nyní, způsobem Spring Data, musíte do svého projektu přidat nějaké změny:

Nejprve najděte soubor mongo-config.xml kam je potřeba přidat:

<!-- 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 je centrální třída podpory MongoDB Spring poskytující sady funkcí pro interakci s databází. Šablona ... poskytuje mapování mezi objekty vaší domény a dokumenty MongoDB . Další informace

Za druhé, ve vaší @Service class, přidejte následující kód, který se má načíst do @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();
}

Poznámka: Oba, Person a Address by měl mít výchozí prázdný konstruktor!




  1. Existuje způsob, jak přinutit mongodb, aby uložil určitý index v paměti ram?

  2. Požadavky na používání transakcí MongoDB

  3. Jak popíšu sbírku v Mongo?

  4. Jak spustit Redis na Amazon OpsWorks pro aplikaci Rails?