2011-05-24 2 views
2

Я использую Doctrine ODM с mongoDB.Doctrine ODM/MongoDB: in AND в запросах

Я пытаюсь делать запросы, как:

$queryBuilder->field('array_field')->in('even_value_1', 'event_value_2'); 
$queryBuilder->field('array_field')->in('odd_value_1', 'odd_value_2'); 

Идея заключается в том, чтобы выбрать все документы, которые имеют в своем

array_field(event_value_1 OR event_value_2) AND (odd_value_1 OR odd_value_2) 

С синтаксисом я использую, я получаю документы, которые имеют

event_value_1 OR event_value_2 OR odd_value_1 OR odd_value_2 

Любые идеи о том, как действовать или если это возможно?

ответ

3

Кажется, что оператор $ и оператор в настоящее время недоступен в MongoDB. в $ и оператор в 1.9.1 (нестабильная версия)

Вот билет на запрос особенность: https://jira.mongodb.org/browse/SERVER-1089

В настоящее время (1.8.x) единственное решение, кажется, использует мультипликатор «$ или» statments нравится:

even_value_1 AND odd_value_1 
OR even_value_1 AND odd_value_2 
OR even_value_2 AND odd_value_1 
OR event_value_2 AND odd_value_2 

EDIT: Вот код, чтобы помочь будущим пользователям

Во-первых, нам нужна функция, чтобы превратить нашу

array_field(event_value_1 OR event_value_2) AND (odd_value_1 OR odd_value_2) 

в

even_value_1 AND odd_value_1 
OR even_value_1 AND odd_value_2 
OR even_value_2 AND odd_value_1 
OR event_value_2 AND odd_value_2 

Вот необходимые функции

/** 
* $pArray for our example should be like array(array(event_value_1, 
*     event_value_2),array(odd_value_1, odd_value_2)) 
*/ 
function transform_and_group_of_or_to_or_group_of_and ($pArray) 
{ 
    //Make sure we have sequential numerical indexes 
    sort($pArray); 

    $maxIndices = array(); 
    foreach ($pArray as $key=>&$values){ 
     //Make sure we have sequential numerical indexes 
     sort($values); 

     $maxIndices[$key] = count($values)-1; 
     $arIndices[$key] = 0; 
    } 

    $groupCount = count($pArray); 
    $groupOfAnd = array(); 

    do { 
     $newGroup = array(); 
     for ($i=0; $i<$groupCount; $i++){ 
      $indice = $arIndices[$i]; 
      $sousTab = $pArray[$i]; 
      $newGroup[] = $sousTab[$indice]; 
     } 
     $groupOfAnd[] = $newGroup; 
    } while(increment_numbers($arIndices, $maxIndices)); 

    return $groupOfAnd; 
} 

function increment_numbers(& $arIndices, $maxIndices){ 
    //Raise the last indice 
    $arIndices[count($arIndices)-1]++; 

    $check = true; 
    for ($i=count($arIndices)-1; (($i>=0) && ($check === true)); $i--){ 
     if ($arIndices[$i] > $maxIndices[$i]){ 
      if ($i > 0){ 
       $arIndices[$i-1]++;//increment the upper indice element 
      } else { 
       return 0; 
      } 
      $arIndices[$i] = 0; 
      $check=true; 
     }else{ 
      $check = false; 
     } 
    } 
    return true; 
} 

Для части Doctrine ODM:

if (count($arGroupedCritere)) { 
     $arGroupedCritere = transform_and_group_of_or_to_or_group_of_and($arGroupedCritere); 
      foreach($arGroupedCritere as $arCritere) { 
       $queryBuilder->addOr($queryBuilder->expr()->field('_criteres')->all($arCritere)); 
      } 
    } 

Надеется, что это помогает

Смежные вопросы