How about performance for the $near operation in mongodb(meteor) - performance

I am using meteor to implement a 'near' query.
In fact, it works well. But I am wondering how about the performance for server side.
This is the code for near query:
var geolocation = Session.get('location');
var lnglat = [0,0];
if(geolocation){
lnglat = [geolocation.longitude,geolocation.latitude];
}
if(Session.get('type') === 'near'){
return Posts.find({
location: {
$near: {
$geometry: {
type: "Point",
coordinates: lnglat
},
$maxDistance: 20000 //meters
}
}
});
}

The best answer lies in the mongodb source code in github (obviously! duh!). According to the documentation, its important to ensure the indexes. Link: http://docs.mongodb.org/manual/core/geospatial-indexes/

Related

graphql-codegen + typescript-svelte-apollo - Refetch not working?

(Edited)
Refetching with the generated query type seems to work different from the refetch function in Apollo Client useQuery. I don't understand how to phrase it - can anyone provide an example?
I'm realizing the problem is probably either my refetch is not properly phrased, or maybe the store is only hitting the cached query. I've been going over my code for days and I can't figure out what it could be. I've tried await blocks too.
The refetch worked with svelte-apollo, but i'm trying to eliminate that dependency. I've also tried Apollo Client's useQuery, but the whole point of graphql-codegen with typescript-svelte-apollo is to use the generated typescript wrapper for the query.
When I assign the generated query to a reactive constant in my Svelte front-end code,
$: observations = getObservations({ variables: { filter } });
the query does not refetch when i update the query variables, as I would expect.
This is how my svelte template is using the query. The filter object changes based on a form user input. I've tried this with an await block too.
<script lang="ts">
import { getObservations } from '$lib/generated';
$: observations = getObservations({ variables: { filter } });
function handleFilter(event) {
filter = event.detail;
}
</script>
{#if $observations.loading}
Loading...
{:else if $observations.error}
{$observations.error}
{:else if $observations.data}
{#each $observations.data['observations']['edges'] as edge}
<Item node={edge['node']} />
{/each}
{/if}
Since this plugin allows to use the query directly, without Apollo's useQuery, i'm not sure how to phrase a refetch.
If i do $observations.refetch(); inside handleFilter(e), i get an error
Property 'refetch' does not exist on type 'Readable<ApolloQueryResult<GetObservationsQuery> & { query: ObservableQuery<GetObservationsQuery, Exact<{ filter?: FilterObservationsInput; }>>; }>'.ts(2339)
There's nothing fancy in my config. Am I doing something wrong here?
schema: src/graphql/schema.graphql
documents:
- src/graphql/queries.graphql
- src/graphql/mutations.graphql
generates:
src/lib/generated.ts:
plugins:
- typescript
- typescript-operations
- graphql-codegen-svelte-apollo
config:
clientPath: src/lib/shared/client
# asyncQuery: true
scalars:
ISO8601Date: Date
ISO8601DateTime: Date
Here's the client:
export default new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
observations: relayStylePagination(),
},
},
},
})
});
The generated query:
export const getObservations = (
options: Omit<
WatchQueryOptions<GetObservationsQueryVariables>,
"query"
>
): Readable<
ApolloQueryResult<GetObservationsQuery> & {
query: ObservableQuery<
GetObservationsQuery,
GetObservationsQueryVariables
>;
}
> => {
const q = client.watchQuery({
query: GetObservationsDoc,
...options,
});
var result = readable<
ApolloQueryResult<GetObservationsQuery> & {
query: ObservableQuery<
GetObservationsQuery,
GetObservationsQueryVariables
>;
}
>(
{ data: {} as any, loading: true, error: undefined, networkStatus: 1, query: q },
(set) => {
q.subscribe((v: any) => {
set({ ...v, query: q });
});
}
);
return result;
}
Here's the query document that it's built from:
query getObservations($filter: FilterObservationsInput) {
observations(filter: $filter) {
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
}
edges {
cursor
node {
id
createdAt
updatedAt
when
where
imgSrcThumb
imgSrcSm
imgSrcMed
thumbImage {
width
height
}
name {
formatName
author
}
user {
name
login
}
rssLog {
detail
}
}
}
}
}

How to modify just a property from a dexie store without deleting the rest?

I'm having the dexie stores showed in the print screen below:
Dexie stores print screen
My goal is to update a dexie field row from a store without losing the rest of the data.
For example: when I edit and save the field "com_name" from the second row (key={2}) I want to update "com_name" only and not lose the rest of the properties, see first and the third row.
I already tried with collection.modify and table.update but both deleted the rest of the properties when used the code below:
dexieDB.table('company').where('dexieKey').equals('{1}')
//USING table.update
//.update(dexieRecord.dexiekey, {
// company: {
// com_name: "TOP SERVE 2"
// }
//})
.modify(
{
company:
{
com_name: TOP SERVE 2
}
}
)
.then(function (updated) {
if (updated)
console.log("Success.");
else
console.log("Nothing was updated.");
})
.catch(function (err) { console.log(err); });
Any idea how can I accomplish that?
Thanks
Alex
You where right to use Table.update or Collection.modify. They should never delete other properties than the ones specified. Can you paste a jsitor.com or jsfiddle repro of that and someone may help you pinpoint why the code doesn't work as expected.
Now that you are saying I realised that company and contact stores are created dynamically and editedRecords store has the indexes explicitly declared therefore when update company or contact store, since dexie doesn't see the indexes will overwrite. I haven't tested it yet but I suspect this is the behaviour.
See the print screen below:
Dexie stores overview
Basically I have json raw data from db and in the browser I create the stores and stores data based on it, see code below:
function createDexieTables(jsonData) { //jsonData - array, is the json from db
const stores = {};
const editedRecordsTable = 'editedRecords';
jsonData.forEach((jsonPackage) => {
for (table in jsonPackage) {
if (_.find(dexieDB.tables, { 'name': table }) == undefined) {
stores[table] = 'dexieKey';
}
}
});
stores[editedRecordsTable] = 'dexieKey, table';
addDataToDexie(stores, jsonData);
}
function addDataToDexie(stores, jsonData) {
dbv1 = dexieDB.version(1);
if (jsonData.length > 0) {
dbv1.stores(stores);
jsonData.forEach((jsonPackage) => {
for (table in jsonPackage) {
jsonPackage[table].forEach((tableRow) => {
dexieDB.table(table).add(tableRow)
.then(function () {
console.log(tableRow, ' added to dexie db.');
})
.catch(function () {
console.log(tableRow, ' already exists.');
});
});
}
});
}
}
This is the json, which I convert to object and save to dexie in the value column and the key si "dexieKey":
[
{
"company": [
{
"dexieKey": "{1}",
"company": {
"com_pk": 1,
"com_name": "CloudFire",
"com_city": "Round Rock",
"serverLastEdit": [
{
"com_pk": "2021-06-02T11:30:24.774Z"
},
{
"com_name": "2021-06-02T11:30:24.774Z"
},
{
"com_city": "2021-06-02T11:30:24.774Z"
}
],
"userLastEdit": []
}
}
]
}
]
Any idea why indexes were not populated when generating them dynamically?
Given the JSON data, i understand what's going wrong.
Instead of passing the following to update():
{
company:
{
com_name: "TOP SERVE 2"
}
}
You probably meant to pass this:
{
"company.com_name": "TOP SERVE 2"
}
Another hint is to do the add within an rw transaction, or even better if you can use bulkAdd() instead to optimize the performance.

Made a query in Watson discovery, tried to duplicate via nodejs sdk and the passages array is empty

After doing a simple natural language query in the build query page, set the options for "include relevant passages to Yes. I get back 5 passages and results. All good. When I try from npm ibm-watson 6 nodejs sdk. I get the results, but an empty passages array with the same natural langauge text.
Here is the the url from the query page showing the options, which I tried all of them
https://api.us-east.discovery.watson.cloud.ibm.com/instances/d45df72b-93e4-4897-b9ac-98dc1e088afc/v1/environments/xx/collections/xx/query?version=2018-12-03&deduplicate=false&highlight=true&passages=true&passages.count=5&natural_language_query=what%20is%20autism
Here is the answer from the query builder page
Here is code example,
var discovery = new watson_discovery_v1({
authenticator : new IamAuthenticator({apikey: msg.startup.discovery_password}),
serviceUrl : msg.startup.discovery_endpoint,
version: '2020-09-22'
});
msg.WDSParams = {
environmentId: "x",
collectionId: "x",
passages: true,
count:5,
natural_language_query: msg.params.input.text
}
discovery.query(msg.WDSParams)
.then(results => {
msg.WDSResults = results; //your query results
node.send(msg);
})
.catch(err => {
console.log('error:', err);
});
Here is the json that came back from the discovery call
I have tried all of the passage options, duplicated the exact options that the query builder used. The same results come back, but no passages. Anyone have an idea? BTW using the Lite plan until I can prove passages works.
The problem was related to the way I called the query method. Below code resolved the issue. This code is for a nodeRed function node.
const watson_discovery_v1 = global.get('watson_discovery_v1');
const { IamAuthenticator } = global.get('ibm_auth');
const discovery = new watson_discovery_v1({
authenticator : new IamAuthenticator({apikey:
msg.startup.discovery_password}),
serviceUrl : msg.startup.discovery_endpoint,
version: '2019-04-30'
});
async function run() {
try {
const result = await discovery.query({
environmentId: 'x',
collectionId: 'x',
passages: true,
passagesCount: 2,
count: 5,
naturalLanguageQuery: msg.params.input.text
})
msg.WDSResults = result
clearTimeout(myTM)
}
catch(e){
node.error(e)
}
node.send(msg);
}
run()

Apollo cache fails when query variables change

I'm using useLazyQuery() to get analytic data measured by a time filter. When the time filter change, the cache returns the same values despite the filter.
I'm using the default fetchPolicy (cache-first).
const [
getVisitorsAnalytics,
{ loading, data },
] = useAnalyticVisitorsLazyQuery()
const handleTimeFilterChange = (timeFilter: string) => {
getVisitorsAnalytics({
variables: {
input: {
timeFilter,
},
},
})
}
Thanks and regards!
I think the values are cached and the cache doesn't have the data for the new filter value passed -
const { data, loading } = useLazyQuery(QUERY, {
fetchPolicy: 'network-only'
});

Filter design documents with PouchDB

I'm using a design document to ensure that only owners can modify docs. How can I prevent couchdb from replicating this design document?
You can use the filter option in changes() and replicate(), e.g.
var opts = {
live: true,
filter: function(doc) {
return doc._id.indexOf('_design') !== 0;
}
};
var db = new PouchDB('todos');
db.replicate.to('http://localhost:5984/todos', opts);

Resources