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

MongoDB:Sådan laver du en tekstsøgning og sorterer efter en dato

Uanset andre sammensatte indeksnøgler skal du inkludere $meta for "textScore" for at få den korrekte sortering:

db.collection.find(
    { "$text": { "$search": "\"[email protected]\""}},
    { "score": { "$meta": "textScore" } }
).sort({
    "score": { "$meta": "textScore" }, "Date": 1
})

Så naturligvis vil du have, at "score" skal sorteres først og derefter efter "Dato", for at tingene bliver korrekt rangeret efter søgningens relevans.

Indeksrækkefølgen er ligegyldig, men du kan selvfølgelig kun have "et" tekstindeks. Så sørg for at droppe alle andre, før du opretter:

db.collection.createIndex({ 
   "From": "text",
   "To": "text",
   "CC":"text", 
   "BCC": "text", 
   "Date":1
})

Se efter indekser, der er aktuelle med:

db.collection.getIndicies()

Eller bare slip alt og start på en frisk:

db.collection.dropIndexes()

For de data, du ser ud til at søge på, ville jeg dog have troet, at et almindeligt sammensat indeks på hvert felt burde passe dig bedre. At lede efter "e-mail"-adresser bør være et "nøjagtigt match", og hvis du forventer flere elementer for hvert felt, skal de være arrays af strenge, som sådan:

{
    "TO": ["[email protected]"],
    "FROM": ["[email protected]"],
    "CC": ["[email protected]","[email protected]"],
    "BCC": [],
    "Date": ISODate("2015-07-27T13:42:05.535Z")
}

Så har du brug for separate indekser på hvert felt, muligvis sammensat med "Dato" som sådan:

db.email.createIndex({ "TO": 1, "Date": 1 })
db.email.createIndex({ "FROM": 1, "Date": 1 })
db.email.createIndex({ "CC": 1, "Date": 1 })
db.email.createIndex({ "BCC": 1, "Date": 1 })

Og forespørg med en $or tilstand:

db.email.find({
    "$or": [
        { "TO": "[email protected]" },
        { "FROM": "[email protected]" },
        { "CC": "[email protected]" },
        { "BCC": "[email protected]" }
    ],
    "Date": { "$lt": new Date() }
})

Hvis du ser på .explain(true) (verbose) output fra det, bør du se, at den vindende plan er et "indeks skæringspunkt" af alle de specificerede indekser. Dette viser sig at være meget effektivt, da hvert felt (og det valgte indeks) har en nøjagtig matchværdi og et intervalmatch på den indekserede dato.

Det vil være meget bedre for dig end den "fuzzy matching" af tekstsøgninger. Selv regulære udtryk burde fungere bedre her generelt (for e-mail-adresser) og især hvis de er "forankrede" ^ til begyndelsen af ​​strengen.

Tekstindekser er beregnet til, at "ordlignende tokens" skal matche, men dette bør ikke være dine data. $or ser ikke pænt ud, men det burde gøre et meget bedre stykke arbejde.




  1. Kan ikke oprette forbindelse til MongoDB-serveren på Google Compute Engine fra anden VM-instans

  2. Hvordan får man nøglen fra værdi i nøgle/værdipar i redis butiksklient?

  3. Hvad skal jeg bruge? Socket.io værelser eller Redis pub-sub?

  4. hvordan man gentager en mongo-markør i en løkke i python