mongo distinct field values

This commit is contained in:
Jan Prochazka 2022-03-17 10:00:11 +01:00
parent 5c4794deae
commit 0d7bfd5f90
4 changed files with 102 additions and 47 deletions

View File

@ -33,6 +33,7 @@
export let pureName = null;
export let schemaName = null;
export let columnName = null;
export let uniqueName = null;
let value;
let isError;
@ -223,7 +224,7 @@
multiselect: true,
schemaName,
pureName,
columnName,
field: columnName || uniqueName,
onConfirm: keys => setFilter(keys.map(x => getFilterValueExpression(x)).join(',')),
});
}
@ -271,7 +272,7 @@
<InlineButton on:click={handleShowDictionary} narrow square>
<FontIcon icon="icon dots-horizontal" />
</InlineButton>
{:else if pureName && columnName}
{:else if (pureName && columnName) || (pureName && uniqueName && driver?.databaseEngineTypes?.includes('document'))}
<InlineButton on:click={handleShowValuesModal} narrow square>
<FontIcon icon="icon dots-vertical" />
</InlineButton>

View File

@ -1535,6 +1535,7 @@
onGetReference={value => (domFilterControlsRef.get()[col.uniqueName] = value)}
foreignKey={col.foreignKey}
columnName={col.uniquePath.length == 1 ? col.uniquePath[0] : null}
uniqueName={col.uniqueName}
pureName={col.pureName}
schemaName={col.schemaName}
{conid}

View File

@ -14,13 +14,14 @@
import FormTextField from '../forms/FormTextField.svelte';
import _ from 'lodash';
import { apiCall } from '../utility/api';
import ErrorInfo from '../elements/ErrorInfo.svelte';
export let onConfirm;
export let conid;
export let database;
export let pureName;
export let schemaName;
export let columnName;
export let field;
export let driver;
export let multiselect = false;
@ -41,7 +42,7 @@
search,
schemaName,
pureName,
field: columnName,
field,
});
isLoading = false;
@ -59,7 +60,7 @@
<FormProvider>
<ModalBase {...$$restProps}>
<svelte:fragment slot="header">Choose value from {columnName}</svelte:fragment>
<svelte:fragment slot="header">Choose value from {field}</svelte:fragment>
<!-- <FormTextField name="search" label='Search' placeholder="Search" bind:value={search} /> -->
<div class="largeFormMarker">
@ -71,51 +72,55 @@
{/if}
{#if !isLoading && rows}
<div class="tableWrapper">
<ScrollableTableControl
{rows}
clickable
on:clickrow={e => {
const { value } = e.detail;
if (multiselect) {
if (checkedKeys.includes(value)) checkedKeys = checkedKeys.filter(x => x != value);
else checkedKeys = [...checkedKeys, value];
} else {
closeCurrentModal();
onConfirm(value);
}
}}
columns={[
multiselect && {
fieldName: 'checked',
header: '',
width: '30px',
slot: 1,
},
{
fieldName: 'value',
header: 'Value',
formatter: row => (row.value == null ? '(NULL)' : row.value),
},
]}
>
<input
type="checkbox"
let:row
slot="1"
checked={checkedKeys.includes(row['value'])}
on:change={e => {
const value = row['value'];
if (e.target.checked) {
if (!checkedKeys.includes(value)) checkedKeys = [...checkedKeys, value];
} else {
{#if rows.errorMessage}
<ErrorInfo message={rows.errorMessage} />
{:else}
<div class="tableWrapper">
<ScrollableTableControl
{rows}
clickable
on:clickrow={e => {
const { value } = e.detail;
if (multiselect) {
if (checkedKeys.includes(value)) checkedKeys = checkedKeys.filter(x => x != value);
else checkedKeys = [...checkedKeys, value];
} else {
closeCurrentModal();
onConfirm(value);
}
e.stopPropagation();
}}
/>
</ScrollableTableControl>
</div>
columns={[
multiselect && {
fieldName: 'checked',
header: '',
width: '30px',
slot: 1,
},
{
fieldName: 'value',
header: 'Value',
formatter: row => (row.value == null ? '(NULL)' : row.value),
},
]}
>
<input
type="checkbox"
let:row
slot="1"
checked={checkedKeys.includes(row['value'])}
on:change={e => {
const value = row['value'];
if (e.target.checked) {
if (!checkedKeys.includes(value)) checkedKeys = [...checkedKeys, value];
} else {
if (checkedKeys.includes(value)) checkedKeys = checkedKeys.filter(x => x != value);
}
e.stopPropagation();
}}
/>
</ScrollableTableControl>
</div>
{/if}
{/if}
<svelte:fragment slot="footer">

View File

@ -277,6 +277,54 @@ const driver = {
const db = pool.db(name);
await db.createCollection('collection1');
},
async loadFieldValues(pool, name, field, search) {
try {
const collection = pool.__getDatabase().collection(name.pureName);
// console.log('options.condition', JSON.stringify(options.condition, undefined, 2));
const pipelineMatch = [];
if (search) {
const tokens = _.compact(search.split(' ').map((x) => x.trim()));
if (tokens.length > 0) {
pipelineMatch.push({
$match: {
$and: tokens.map((token) => ({
[field]: {
$regex: `.*${token}.*`,
$options: 'i',
},
})),
},
});
}
}
let cursor = await collection.aggregate([
...pipelineMatch,
{
$group: { _id: '$' + field },
},
{
$sort: { _id: 1 },
},
{
$limit: 100,
},
]);
const rows = await cursor.toArray();
return _.uniqBy(
rows.map(transformMongoData).map(({ _id }) => {
if (_.isArray(_id) || _.isPlainObject(_id)) return { value: null };
return { value: _id };
}),
(x) => x.value
);
} catch (err) {
return { errorMessage: err.message };
}
},
};
module.exports = driver;