Du forsøger at sortere på et metafelt, ikke et normalt feltnavn.
Det andet argument til $collection->find()
bestemmer, hvilke felter i dokumentet du (vil/ikke) ønsker skal returneres af forespørgslen.
Dette svarer til SELECT *...
vs SELECT field1, field2 ...
i SQL-databaser.
Nu, i MongoDB 2.6 er der et ekstra nøgleord, du kan bruge her, $meta. Dette nøgleord giver dig mulighed for at "injicere" feltnavne i returdokumentet (som ellers ikke ville eksistere). Værdien af dette indsprøjtede feltnavn ville komme fra en slags "metadata" for det dokument eller den forespørgsel, du udfører.
$text-forespørgselsoperatoren er et eksempel på en operator, der har mere information tilgængelig om det matchede dokument. Desværre har den ingen mulighed for at fortælle dig om denne ekstra information, da det ville manipulere dit dokument på en uventet måde. Det vedhæfter dog en metadata til dokumentet - og det er op til dig at beslutte, om du har behov for det eller ej.
De metadata, som $text-operatoren opretter, bruger søgeordet "textScore". Hvis du vil inkludere disse data, kan du gøre det ved at tildele dem til et feltnavn efter eget valg:
array("myFieldname" => array('$meta' => 'keyword'))
I tilfælde af $tekstsøgning (textScore) kan vi f.eks. indsætte feltnavnet "score" i vores dokument ved at overføre dette array som det 2. argument til $collection->find()
:
array("score" => array('$meta' => 'textScore'))
Nu har vi indsat et felt kaldet "score" i vores returdokument, som har "textScore"-værdien fra $text-søgningen.
Men da dette stadig kun er metadata for dokumentet, skal du stadig referere til det som $metadata, hvis du vil fortsætte med at bruge denne værdi i eventuelle efterfølgende operationer, før du udfører forespørgslen.
Det betyder, at for at sortere på feltet skal du sortere på $meta-projektionen
array('score' => array('$meta' => 'textScore'))
Dit fulde eksempel bliver så:
<?php
$mc = new MongoClient();
$collection = $mc->selectCollection("myDatabase", "myCollection");
$string = "search string";
$cursor = $collection->find(
array('$text' => array('$search' => $string)),
array('score' => array('$meta' => 'textScore'))
);
$cursor = $cursor->sort(
array('score' => array('$meta' => 'textScore'))
);
foreach($cursor as $document) {
var_dump($document);
}