Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use routine to filter precomputed data #1810

Merged
merged 7 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"filter",
"get-fields",
"graph-by",
"graph-by-precomputed",
"group-and-sum-with",
"hello-world",
"istex-facet",
Expand All @@ -42,6 +43,7 @@
"syndication-from",
"syndication",
"total-of",
"tree-by-precomputed",
"tree-by",
"unwind-by"
],
Expand Down Expand Up @@ -101,10 +103,5 @@
"precomputedBaseUrlForDevelopment": "{public url of the server accessible from webhooks (ie ngrok)}",
"precomputedAnswerMode": "retrieve",
"activateBullDashboard": false,
"themes": [
"void",
"nougat",
"inist",
"istex"
]
"themes": ["void", "nougat", "inist", "istex"]
}
135 changes: 71 additions & 64 deletions packages/ezsLodex/src/buildContext.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import mongoDatabase from './mongoDatabase';
import getPublishedDatasetFilter from './getPublishedDatasetFilter';

const findAll = async (collection) => collection
.find({})
.sort({ position: 1, cover: 1 })
.toArray();
const findAll = async collection =>
collection
.find({})
.sort({ position: 1, cover: 1 })
.toArray();

const findSearchableNames = async (collection) => {
const findSearchableNames = async collection => {
const searchableFields = await collection
.find({ searchable: true })
.toArray();

return searchableFields.map(({ name }) => name);
};

const findFacetNames = async (collection) => {
const searchableFields = await collection
.find({ isFacet: true })
.toArray();
const findFacetNames = async collection => {
const searchableFields = await collection.find({ isFacet: true }).toArray();

return searchableFields.map(({ name }) => name);
};
Expand All @@ -31,65 +30,73 @@ const findFacetNames = async (collection) => {
* @param {String} [host] to set host (usefull to build some links)
* @returns {Object}
*/
export const createFunction = () => async function LodexBuildContext(data, feed) {
if (this.isLast()) {
return feed.close();
}
export const createFunction = () =>
async function LodexBuildContext(data, feed) {
if (this.isLast()) {
return feed.close();
}

const connectionStringURI = this.getParam('connectionStringURI', 'mongodb://ezmaster_db:27017');
const db = await mongoDatabase(connectionStringURI);
const collection = db.collection('field');
const precomputedName = this.getParam('precomputedName');

const host = this.getParam('host');
const {
uri,
maxSize,
skip,
maxValue,
minValue,
match,
orderBy = '_id/asc',
invertedFacets = [],
$query,
field,
...facets
} = data;
const searchableFieldNames = await findSearchableNames(collection);
const facetFieldNames = await findFacetNames(collection);
const fields = await findAll(collection);
const filter = getPublishedDatasetFilter({
uri,
match,
invertedFacets,
facets,
...$query,
searchableFieldNames,
facetFieldNames,
});
const connectionStringURI = this.getParam(
'connectionStringURI',
'mongodb://ezmaster_db:27017',
);

if (filter.$and && !filter.$and.length) {
delete filter.$and;
}
// context is the intput for LodexReduceQuery & LodexRunQuery & LodexDocuments
const context = {
// /*
// to build the MongoDB Query
filter,
field,
fields,
// Default parameters for ALL scripts
maxSize,
maxValue,
minValue,
orderBy,
skip,
uri,
host,
// to allow script to connect to MongoDB
connectionStringURI,
const db = await mongoDatabase(connectionStringURI);
const collection = db.collection('field');

const host = this.getParam('host');
const {
uri,
maxSize,
skip,
maxValue,
minValue,
match,
orderBy = '_id/asc',
invertedFacets = [],
$query,
field,
...facets
} = data;
const searchableFieldNames = await findSearchableNames(collection);
const facetFieldNames = await findFacetNames(collection);
const fields = await findAll(collection);
const filter = getPublishedDatasetFilter({
uri,
match,
invertedFacets,
facets,
...$query,
searchableFieldNames,
facetFieldNames,
});

if (filter.$and && !filter.$and.length) {
delete filter.$and;
}
// context is the intput for LodexReduceQuery & LodexRunQuery & LodexDocuments
const context = {
// /*
// to build the MongoDB Query
filter,
field,
fields,
// Default parameters for ALL scripts
maxSize,
maxValue,
minValue,
orderBy,
skip,
uri,
host,
// to allow script to connect to MongoDB
connectionStringURI,
precomputedName,
};
feed.send(context);
};
feed.send(context);
};

export default {
buildContext: createFunction(),
Expand Down
73 changes: 73 additions & 0 deletions packages/ezsLodex/src/filterPrecomputed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import mongoDatabase from './mongoDatabase';
import { Readable } from 'stream';

/**
* Take `Object` containing a MongoDB query and throw the result
*
* The input object must contain a `connectionStringURI` property, containing
* the connection string to MongoDB.
*
* @name LodexFilterPrecomputed
* @param {Object} [referer] data injected into every result object
* @returns {Object}
*/
export const createFunction = () =>
async function LodexFilterPrecomputed(data, feed) {
const {
connectionStringURI,
filter: rawFilter,
precomputedName,
} = this.getEnv();
const collectionName = 'precomputed';
const isFilter =
rawFilter &&
Object.keys(rawFilter).filter(
key => key != 'removedAt' && rawFilter[key] != null,
).length > 0;

const db = await mongoDatabase(connectionStringURI);
const collection = db.collection(collectionName);
const precomputedData = (
await collection.findOne({
name: precomputedName,
})
).data;

if (!isFilter) {
//With unfiltered precomputed data, we can send the whole precomputed Data directly
precomputedData.map(item => feed.write(item));
feed.end();
return feed.close();
}

const filteredItems = precomputedData.filter(
item => item.origin[0] === (data || {}).uri,
);

const { ezs } = this;
const total = await filteredItems.length;
if (total === 0) {
return feed.send({ total: 0 });
}
const path = ['total'];
const value = [total];

if (this.isLast()) {
return feed.close();
}

const readableStream = new Readable({
read() {
filteredItems.map(item => this.push(item));
this.push(null);
},
objectMode: true,
});

readableStream.pipe(ezs('assign', { path, value }));
await feed.flow(readableStream);
};

export default {
filterPrecomputed: createFunction(),
};
3 changes: 3 additions & 0 deletions packages/ezsLodex/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import JSONLDCompacter from './JSONLDCompacter';
import JSONLDString from './JSONLDString';
import JSONLDObject from './JSONLDObject';
import disabled from './disabled';
import filterPrecomputed from './filterPrecomputed';
import runQuery from './runQuery';
import reduceQuery from './reduceQuery';
import formatOutput from './formatOutput';
Expand Down Expand Up @@ -55,6 +56,7 @@ const funcs = {
injectSyndicationFrom,
injectCountFrom,
labelizeFieldID,
filterPrecomputed,
runQuery,
reduceQuery,
formatOutput,
Expand All @@ -72,6 +74,7 @@ const funcs = {
LodexGetFields: getFields.getFields,
LodexGetCharacteristics: getCharacteristics.getCharacteristics,
LodexDocuments: runQuery.runQuery,
LodexFilterPrecomputed: filterPrecomputed.filterPrecomputed,
LodexRunQuery: runQuery.runQuery,
LodexReduceQuery: reduceQuery.reduceQuery,
LodexOutput: formatOutput.formatOutput,
Expand Down
Loading