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

MongoDB forespørger optimering

Det du ønsker er et "facetteret søgning" resultat, hvor du har statistikken over de matchede termer i det aktuelle resultatsæt. Efterfølgende, mens der er produkter, der "synes" at udføre alt arbejdet i et enkelt svar, skal du overveje, at de fleste generiske lagringsmotorer vil have brug for flere operationer.

Med MongoDB kan du bruge to forespørgsler til at få selve resultaterne og en anden til at få facetinformationen. Dette ville give resultater svarende til de facetterede resultater, der er tilgængelige fra dedikerede søgemaskineprodukter som Solr eller ElasticSearch.

Men for at gøre dette effektivt, ønsker du at inkludere dette i dit dokument på en måde, det kan bruges effektivt. En meget effektiv form for det, du ønsker, er at bruge en række tokeniserede data:

 {
     "otherData": "something",
     "facets": [
         "country:UK",
         "city:London-UK",
         "genre:Student"
     ]
 }

Så "factetter" er et enkelt felt i dit dokument og ikke flere steder. Dette gør det meget nemt at indeksere og forespørge. Så kan du effektivt aggregere på tværs af dine resultater og få totalerne for hver facet:

User.aggregate(
    [
        { "$unwind": "$facets" },
        { "$group": {
            "_id": "$facets",
            "count": { "$sum": 1 }
        }}
    ],
    function(err,results) {

    }
);

Eller mere ideelt med nogle kriterier i $match :

User.aggregate(
    [
        { "$match": { "facets": { "$in": ["genre:student"] } } },
        { "$unwind": "$facets" },
        { "$group": {
            "_id": "$facets",
            "count": { "$sum": 1 }
        }}
    ],
    function(err,results) {

    }
);

Giver i sidste ende et svar som:

{ "_id": "country:FR", "count": 50 },
{ "_id": "country:UK", "count": 300 },
{ "_id": "city:London-UK", "count": 150 },
{ "_id": "genre:Student": "count": 500 }

En sådan struktur er let at krydse og inspicere for ting som det diskrete "land" og "byen", der hører til et "land", da disse data bare er adskilt konsekvent af en bindestreg "-".

Det er en dårlig idé at prøve at mash-up dokumenter i arrays. Der er en BSON-størrelsesgrænse på 16 MB, der også skal respekteres, hvorfra resultaterne af sammenmaskning (især hvis du forsøger at beholde dokumentindholdet) helt sikkert vil ende med at blive overskredet i svaret.

For noget så simpelt som at få det "overordnede antal" af resultater fra en sådan forespørgsel, så opsummer du bare elementerne i en bestemt facettype. Eller send bare dine samme forespørgselsargumenter til en .count() operation:

User.count({ "facets": { "$in": ["genre:Student"] } },function(err,count) {

});

Som sagt her, især når du implementerer "paging" af resultater, så er rollerne for at få "Resultattælling", "Facettælling" og den faktiske "Resultatside" alle delegeret til "separate" forespørgsler til serveren.

Der er intet galt i at indsende hver af disse forespørgsler til serveren parallelt og derefter kombinere en struktur til feed til din skabelon eller applikation, der ligner det facetterede søgeresultat fra et af søgemaskineprodukterne, der tilbyder denne form for svar.

Afsluttende

Så læg noget i dit dokument for at markere facetterne et enkelt sted. En række tokeniserede strenge fungerer godt til dette formål. Det fungerer også godt med forespørgselsformularer såsom $in og $all for enten "eller" eller "og"-betingelser på facetvalgskombinationer.

Forsøg ikke at maske resultater eller tilføje tilføjelser bare for at matche en eller anden opfattet hierarkisk struktur, men gennemse de modtagne resultater og bruge simple mønstre i tokens. Det er meget nemt at

Kør sideforespørgsler for indholdet som separate forespørgsler til enten facetter eller overordnede tæller. At forsøge at skubbe alt indhold i arrays og derefter begrænse ud bare for at få tæller giver ikke mening. Det samme ville gælde for en RDBMS-løsning til at gøre det samme, hvor personsøgningsresultatet tæller og den aktuelle side er separate forespørgselsoperationer.

Der er mere information skrevet på MongoDB-bloggen om facetteret søgning med MongoDB, der også forklarer nogle andre muligheder. Der er også artikler om integration med eksterne søgeløsninger ved hjælp af mongoconnector eller andre tilgange.




  1. Hvad er de underliggende forskelle mellem select, epoll, kqueue og evport?

  2. Indsæt en Pandas Dataframe i mongodb ved hjælp af PyMongo

  3. Redis - Brug af Incr-værdi i en transaktion

  4. Kom godt i gang med PHP og MongoDB