sql >> Databasteknik >  >> NoSQL >> MongoDB

MongoDB:Hur man gör en textsökning och sorterar efter ett datum

Oavsett andra sammansatta indexnycklar måste du inkludera $meta för "textScore" för att få rätt sortering:

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

Så naturligtvis vill du att "poängen" ska sorteras först och sedan efter "Datum" för att saker och ting ska rangordnas korrekt efter sökningens relevans.

Ordningen på index spelar ingen roll, men självklart kan du bara ha "ett" textindex. Så se till att du släpper alla andra innan du skapar:

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

Leta efter index som är aktuella med:

db.collection.getIndicies()

Eller bara släpp allt och börja om på nytt:

db.collection.dropIndexes()

För de data du verkar söka på skulle jag dock ha trott att ett vanligt sammansatt index på varje fält borde passa dig bättre. Att leta efter "e-postadresser" bör vara en "exakt matchning", och om du förväntar dig flera objekt för varje fält bör de vara uppsättningar av strängar, som så:

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

Sedan behöver du separata index på varje fält, eventuellt i sammansatt "Datum" så här:

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

Och fråga med en $or skick:

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

Om du tittar på .explain(true) (omfattande) utdata från det, bör du se att den vinnande planen är en "index skärningspunkt" av alla angivna index. Detta verkar vara mycket effektivt eftersom varje fält (och index som valts) har ett exakt matchningsvärde och en intervallmatchning på det indexerade datumet.

Det kommer att bli mycket bättre för dig än den "suddiga matchningen" av textsökningar. Även reguljära uttryck borde fungera bättre här generellt (för e-postadresser) och speciellt om de är "förankrade" ^ till början av strängen.

Textindex är avsedda för att "ordliknande tokens" ska matcha, men detta bör inte vara din data. $or ser inte bra ut, men den borde göra ett mycket bättre jobb.




  1. Reactivemongo serialiserar en karta till ett BSONDocument

  2. Mongodb:`com.mongodb.MongoSocketReadException:För tidigt nådd slutet av strömmen` med morfia

  3. Mongo Age Group Aggregation

  4. Mongo DB-objekt-ID avserialiseras med JSON-serialiserare