mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
CE-1405 / CE-1479 - add queryInput.fieldNamesToInclude
This commit is contained in:
@ -41,6 +41,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.JoinsContext;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.tables.query.expressions.AbstractFilterExpression;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
@ -176,18 +177,28 @@ public class AbstractMongoDBAction
|
||||
/*******************************************************************************
|
||||
** Convert a mongodb document to a QRecord.
|
||||
*******************************************************************************/
|
||||
protected QRecord documentToRecord(QTableMetaData table, Document document)
|
||||
protected QRecord documentToRecord(QueryInput queryInput, Document document)
|
||||
{
|
||||
QRecord record = new QRecord();
|
||||
QTableMetaData table = queryInput.getTable();
|
||||
QRecord record = new QRecord();
|
||||
|
||||
record.setTableName(table.getName());
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// build the set of field names to include //
|
||||
/////////////////////////////////////////////
|
||||
Set<String> fieldNamesToInclude = queryInput.getFieldNamesToInclude();
|
||||
List<QFieldMetaData> selectedFields = table.getFields().values()
|
||||
.stream().filter(field -> fieldNamesToInclude == null || fieldNamesToInclude.contains(field.getName()))
|
||||
.toList();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// first iterate over the table's fields, looking for them (at their backend name (path, //
|
||||
// if it has dots) inside the document note that we'll remove values from the document //
|
||||
// as we go - then after this loop, will handle all remaining values as unstructured fields //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Map<String, Serializable> values = record.getValues();
|
||||
for(QFieldMetaData field : table.getFields().values())
|
||||
for(QFieldMetaData field : selectedFields)
|
||||
{
|
||||
String fieldName = field.getName();
|
||||
String fieldBackendName = getFieldBackendName(field);
|
||||
|
@ -41,6 +41,7 @@ import com.kingsrook.qqq.backend.module.mongodb.model.metadata.MongoDBBackendMet
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.model.Projections;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
@ -96,6 +97,15 @@ public class MongoDBQueryAction extends AbstractMongoDBAction implements QueryIn
|
||||
////////////////////////////////////////////////////////////
|
||||
FindIterable<Document> cursor = collection.find(mongoClientContainer.getMongoSession(), searchQuery);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// if input specifies a set of field names to include, then add a 'projection' to the cursor //
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(queryInput.getFieldNamesToInclude() != null)
|
||||
{
|
||||
List<String> backendFieldNames = queryInput.getFieldNamesToInclude().stream().map(f -> getFieldBackendName(table.getField(f))).toList();
|
||||
cursor.projection(Projections.include(backendFieldNames));
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// add a sort operator if needed //
|
||||
///////////////////////////////////
|
||||
@ -138,7 +148,7 @@ public class MongoDBQueryAction extends AbstractMongoDBAction implements QueryIn
|
||||
actionTimeoutHelper.cancel();
|
||||
setQueryStatFirstResultTime();
|
||||
|
||||
QRecord record = documentToRecord(table, document);
|
||||
QRecord record = documentToRecord(queryInput, document);
|
||||
queryOutput.addRecord(record);
|
||||
|
||||
if(queryInput.getAsyncJobCallback().wasCancelRequested())
|
||||
|
@ -29,6 +29,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
@ -54,6 +55,8 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -994,4 +997,46 @@ class MongoDBQueryActionTest extends BaseTest
|
||||
.allMatch(r -> r.getValueInteger("storeKey").equals(1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testFieldNamesToInclude() throws QException
|
||||
{
|
||||
QQueryFilter filter = new QQueryFilter().withCriteria("firstName", QCriteriaOperator.EQUALS, "Darin");
|
||||
QueryInput queryInput = new QueryInput(TestUtils.TABLE_NAME_PERSON).withFilter(filter);
|
||||
|
||||
QRecord record = new QueryAction().execute(queryInput.withFieldNamesToInclude(null)).getRecords().get(0);
|
||||
assertTrue(record.getValues().containsKey("id"));
|
||||
assertTrue(record.getValues().containsKey("firstName"));
|
||||
assertTrue(record.getValues().containsKey("createDate"));
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// note, we get an extra "metaData" field (??), which, i guess is expected? //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
assertEquals(QContext.getQInstance().getTable(TestUtils.TABLE_NAME_PERSON).getFields().size() + 1, record.getValues().size());
|
||||
|
||||
record = new QueryAction().execute(queryInput.withFieldNamesToInclude(Set.of("id", "firstName"))).getRecords().get(0);
|
||||
assertTrue(record.getValues().containsKey("id"));
|
||||
assertTrue(record.getValues().containsKey("firstName"));
|
||||
assertFalse(record.getValues().containsKey("createDate"));
|
||||
assertEquals(2, record.getValues().size());
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// here, we'd have put _id (which mongo always returns) as "id", since caller requested it. //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
assertFalse(record.getValues().containsKey("_id"));
|
||||
|
||||
record = new QueryAction().execute(queryInput.withFieldNamesToInclude(Set.of("homeTown"))).getRecords().get(0);
|
||||
assertFalse(record.getValues().containsKey("id"));
|
||||
assertFalse(record.getValues().containsKey("firstName"));
|
||||
assertFalse(record.getValues().containsKey("createDate"));
|
||||
assertTrue(record.getValues().containsKey("homeTown"));
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// here, mongo always gives back _id (but, we won't have re-mapped it to "id", since caller didn't request it), so, do expect 2 fields here //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
assertEquals(2, record.getValues().size());
|
||||
assertTrue(record.getValues().containsKey("_id"));
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user