MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Encontre um documento mongodb usando uma string _id parcial


O $regex e MongoRegex (ou seja, um tipo de regex BSON usado em uma correspondência de igualdade) suporta apenas correspondência com strings, portanto, você não pode usá-los diretamente com um ObjectId.

Em relação ao seu último exemplo de código, você tentou usar $where em um construtor MongoRegex:
$searchTermsAny[] = array(
    $dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
    '$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);

MongoRegex O construtor de recebe uma única string (por exemplo, /foo/i ), do qual deriva o padrão e os sinalizadores. $where destina-se a ser usado como um operador de consulta de nível superior (não associado a nenhum nome de campo). Eu não sigo o que você está fazendo com $dataProps[$i] , mas vamos supor que você esteja construindo um único $where query para corresponder à representação de string de um ObjectId. O documento de consulta teria a seguinte aparência:
{ $where: 'this._id.str.match(/00005/)' }

Observe que estou acessando o str aqui em vez de invocar toString() . Isso porque toString() na verdade, retorna a representação shell do ObjectId. Você pode ver isso verificando sua origem no shell:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
    return "ObjectId(" + tojson(this.str) + ")";
}

Além disso, se você está simplesmente verificando se existe uma substring no _id , você pode usar indexOf() (com um != -1 comparação) em vez de match() com um regex.

Dito isso, usando $where geralmente é uma má ideia se você não estiver combinando com critérios de consulta adicionais que podem usar um índice. Isso ocorre porque $where invoca o interpretador JavaScript para cada documento considerado no conjunto de resultados. Se você combiná-lo com outros critérios mais seletivos, o MongoDB pode usar um índice e restringir os documentos que ele precisa avaliar com $where; no entanto, você terá um mau momento se estiver usando $where e digitalizar muitos documentos ou uma digitalização de mesa no pior dos casos.

Você provavelmente é melhor criar um segundo campo em cada documento que contenha a representação de string hexadecimal do _id . Em seguida, você pode indexar esse campo e consultá-lo usando um regex. As consultas de regex não ancoradas ainda serão um pouco ineficientes (consulte:uso de índice regex nos documentos), mas isso ainda deve ser muito mais rápido do que usar $where .

Esta solução (duplicando o _id string) incorrerá em algum armazenamento adicional por documento, mas você pode decidir que os 24-30 bytes adicionais (carga útil de string e um nome de campo curto) são insignificantes.