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

Najděte místo v uloženém kruhu

Ještě optimálnější než originál, nyní můžete použít $expr v rámci $match fázi po počátečním $geoNear :

db.collection.aggregate([
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [ 23.027573, 72.50675800000001 ],
        },
        "distanceField": "distance"
    }},
    { "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])

Vlastně o něco optimálnější než při prvním napsání. Nyní můžeme jen $redact spíše než $project boolean a $match později:

db.collection.aggregate([
    // Match documents "near" the queried point
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [ 23.027573, 72.50675800000001 ],
        },
        "distanceField": "distance"
    }},

    // Calculate if distance is within radius and remove if not
    { "$redact": {
        "$cond": {
            "if": { "$lte": [ "$distance", "$radius" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }}
])

Informace jste uložili přesně tak, jak jste měli, ale k získání výsledků existuje jiný přístup, než si myslíte.

To, co chcete použít, je $geoNear a konkrétně rámec agregace formulář tohoto operátora. Zde je to, co děláte:

db.collection.aggregate([
    // Match documents "near" the queried point
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [ 23.027573, 72.50675800000001 ],
        },
        "distanceField": "distance"
    }},

    // Calculate if distance is within radius
    { "$project": {
        "location": 1,
        "radius": 1,
        "distance": 1,
        "within": { "$lte": [ "$distance", "$radius" ] }
    }},

    // Match only documents within the radius
    { "$match": { "within": true } }
])

Takže tento formulář umožňuje, aby byla ve výsledcích "promítnuta" vzdálenost od dotazovaného bodu, zatímco dotaz také vrátí pouze nejbližší dokumenty.

Pak použijete logické srovnání, abyste zjistili, zda je hodnota "vzdálenost" menší než "poloměr", tedy v rámci kruhu.

Nakonec srovnáte, abyste odfiltrovali pouze ty výsledky, u kterých bylo tvrzení „uvnitř“ pravdivé.

Do $geoNear můžete přidat další možnosti jak je uvedeno v dokumentaci. Také bych důrazně navrhoval, aby vaše úložiště také používalo formát GeoJSON, protože ten bude pravděpodobně kompatibilnější s jakýmikoli jinými knihovnami, které byste mohli použít k práci na získaných výsledcích.



  1. Jak nastavím cluster elasticache redis jako slave?

  2. Jak zjistit, zda je sidekiq připojen k serveru redis?

  3. Jak zadat preferenci čtení v dotazech Meteor mongo

  4. (Angular 2) Jak vyplnit rozevírací seznam na základě jiného výběru rozevíracího seznamu