Is there a way, using a FTS search, to limit the result list to specific model types?
Also, is there a way to group the results of a FTS search?
Example:
Node 1
prop_A: ABC
prop_B: 1/1/2013
prop_C: this is some string description specific to node 1
prop_D: 1
Node 2
prop_A: ABC
prop_B: 1/1/2013
prop_C: this is some string description specific to node 2
prop_D: 1
Node 3
prop_A: DEF
prop_B: 1/2/2013
prop_C: this is some string description specific to node 3
prop_D: 1
Can you create a query that returns just Node 1 and Node 3? Node 1 and Node 2 should be grouped together because of the same prop_A and prop_B property values.
I'm using the javascript webscript search object.
var queryDef =
{
query: "=prop_A:ABC",
language: "fts-alfresco",
onerror: "exception"
};
try
{
model.articles = [];
var nodes = search.query( queryDef );
}
catch(e) {}
Two questions here:
"Is there a way, using a FTS search, to limit the result list to specific model types?"
use the TYPE:"cm:content" clause to narrow results by type.
For the grouping question, you should look for an example of the solr facet support in Alfresco and check if this fits your requirements.
Related
I'm making a HTTP request to a REST API I created which contains two tables in the DBMS, the main table is called Levels looks like this
Levels:
leve_id: 1
level: "Level 1"
I have a child table called Units that looks like this
Units:
primary_id: 1
unit: "Unit 1"
unit_id: 1 ,foreign key to level_id
I have inserted "unit 1" and "unit 2" to this table and they both have the unit_id: equal to 1 because I want them in Level 1.
Now, the problem is when I'm trying to use a forEach loop in swiftUI to show the units.
struct UnitView: View {
#StateObject var unitVm = UnitViewModel()
var body: some View {
List(unitVm.units, id:\.idUnit){ unit in
Text(unit.unit)
}
}
}
It gives me an error of "ID 1 occurs multiple times"
Which is understandable since the foreign keys aren't unique,
could anyone point me in the right direction to show multiple units with the same id in a particular level?
It's a bit unclear what data you're working with, exactly, in terms of the UnitViewModel, but I'm guessing that it's a direct translation of the Units table, ie with four fields corresponding to: primary_id, unit, unit_id, and level_id.
For the purposes of the swiftUI List, it just needs each item to be uniquely identifiable (eg when you say scrollTo(someItemID)), so you should just supply it the path to your primary_id (which I assume is unique for the whole table) and all should work well. It won't care about the duplicates in idUnit, at that point.
I'm new to DynamoDB and I'm trying to query a table from javascript using the Dynamoose library. I have a table with a primary partition key of type String called "id" which is basically a long string with a user id. I have a second column in the table called "attributes" which is a DynamoDB map and is used to store arbitrary user attributes (I can't change the schema as this is how a predefined persistence adapter works and I'm stuck working with it for convenience).
This is an example of a record in the table:
Item{2}
attributes Map{2}
10 Number: 2
11 Number: 4
12 Number: 6
13 Number: 8
id String: YVVVNIL5CB5WXITFTV3JFUBO2IP2C33BY
The numeric fields, such as the "12" field, in the Map can be interpreted as "week10", "week11","week12" and "week13" and the numeric values 2,4,6 and 8 are the number of times the application was launched that week.
What I need to do is get all user ids of the records that have more than 4 launches in a specific week (eg week 12) and I also need to get the list of user ids with a sum of 20 launches in a range of four weeks (eg. from week 10 to 13).
With Dynamoose I have to use the following model:
dynamoose.model(
DYNAMO_DB_TABLE_NAME,
{id: String, attributes: Map},
{useDocumentTypes: true, saveUnknown: true}
);
(to match the table structure generated by the persistence adapter I'm using).
I assume I will need to do DynamoDB "scan" to achieve this rather than a "query" and I tried this to get started and get a records where week 12 equals 6 to no avail (I get an empty set as result):
const filter = {
FilterExpression: 'contains(#attributes, :val)',
ExpressionAttributeNames: {
'#attributes': 'attributes',
},
ExpressionAttributeValues: {
':val': {'12': 6},
},
};
model.scan(filter).all().exec(function (err, result, lastKey) {
console.log('query result: '+ JSON.stringify(result));
});
If you don't know Dynamoose but can help with solving this via the AWS SDK tu run a DynamoDB scan directly that might also be helpful for me.
Thanks!!
Try the following.
const filter = {
FilterExpression: '#attributes.#12 = :val',
ExpressionAttributeNames: {
'#attributes': 'attributes',
'#12': '12'
},
ExpressionAttributeValues: {
':val': 6,
},
};
Sounds like what you are really trying to do is filter the items where attributes.12 = 6. Which is what the query above will do.
Contains can't be used for objects or arrays.
I'm trying to copy a vertex node and retain it's relationships in ArangoDB. I'm getting a "access after data-modification" error (1579). It doesn't like it when I iterate over the source node's edges and insert an edge copy within the loop. This makes sense but I'm struggling to figure out how to do what I'm wanting within a single transaction.
var query = arangojs.aqlQuery`
let tmpNode = (FOR v IN vertices FILTER v._id == ${nodeId} RETURN v)[0]
let nodeCopy = UNSET(tmpNode, '_id', '_key', '_rev')
let nodeCopyId = (INSERT nodeCopy IN 'vertices' RETURN NEW._id)[0]
FOR e IN GRAPH_EDGES('g', ${nodeId}, {'includeData': true, 'maxDepth': 1})
let tmpEdge = UNSET(e, '_id', '_key', '_rev')
let edgeCopy = MERGE(tmpEdge, {'_from': nodeCopyId})
INSERT edgeCopy IN 'edges'
`;
This quesion is somewhat similar to 'In AQL how to re-parent a vertex' - so let me explain this in a similar way.
One should use the ArangoDB 2.8 pattern matching traversals to solve this.
We will copy Alice to become Sally with similar relations:
let alice=DOCUMENT("persons/alice")
let newSally=UNSET(MERGE(alice, {_key: "sally", name: "Sally"}), '_id')
let r=(for v,e in 1..1 ANY alice GRAPH "knows_graph"
LET me = UNSET(e, "_id", "_key", "_rev")
LET newEdge = (me._to == "persons/alice") ?
MERGE(me, {_to: "persons/sally"}) :
MERGE(me, {_from: "persons/sally"})
INSERT newEdge IN knows RETURN newEdge)
INSERT newSally IN persons RETURN newSally
We therefore first load Alice. We UNSET the properties ArangoDB should set on its own. We change the properties that have to be uniq to be uniq for Alice so we have a Sally afterwards.
Then we open a subquery to traverse ANY first level relations of Alice. In this subequery we want to copy the edges - e. We need to UNSET once more the document attributes that have to be autogenerated by ArangoDB. We need to find out which side of _from and _to pointed to Alice and relocate it to Sally.
The final insert of Sally has to be outside of the subquery, else this statement will attempt to insert one Sally per edge we traverse. We can't insert Saly in front of the query as you already found out - no subsequent fetches are allowed after the insert.
Since firebase not support any spatial indexing then I use geohash which someone advice here.
Geohash is using characters to find the nearby.
So let say I have w22qt4vhye1c w99qt4vdf4vc w22qt4vhzerct geohash store in firebase and I want to query only which geohash close to w22qt4.
How to do that?
I know firebase has startAt. I tried but not work.
UPDATE
Storing geohash to firebase
//Encode lat lng, result w22qt4vhye1c3
var geoHashLatLng = encodeGeoHash(lat,lng);
firebaseRef.child('/geohash/' + geoHashLatLng).set(id);
so in json
root
- geohash
- w22qt4vhye1c3
- id
- z99qt4vdf4vc
- w22qt4vhzerct
My question here.
I Just want to query geohash which start from characters w22qt4. Can we do that in firebase?
UPDATE 2
startAt() seems like not query with characters start with ...
Example: I have following gehash
geohash node
geohash
- a123
- a333
- b123
- c123
- d123
With the following code
var firebaseRef = new Firebase('https://test.firebaseio.com');
var query = firebaseRef.child('/geohash').startAt(null, 'a');
query.on('child_added', function(snapshot) {
console.log(snapshot.name());
});
Will get this results
startAt(null, 'a') //return a123, a333, b123, c123, d123
startAt(null, 'c123') //return c123, d123
startAt(null, 'd') //return d123
My expected results
startAt(null, 'a') //return a123, a333
startAt(null, 'c123') //return c123
startAt(null, 'd') //return d123
My guess, startAt() will query the 26 alphabet letters in sequence but not matching.
So, what can I do in firebase so I can get my expected results above?
In addition to Andrew's answer above, what you want to do to get the desired effect with geohashes (i.e. be able to do prefix queries that let you specify accuracy in the 'query', specifically, for example every 3 characters in the geohash gets you ~ +-80km) is to store the data in a more granular and discretized manner.
So, rather than how you're storing it now, you'll want to save the data by chopping the geohash string key into fragments (I've done it at the 3 character boundary, but you should choose an appropriate tokenization strategy that gives you the desired accuracy) and use each fragment as a child name, as such:
root
- geohash
- w22
- qt4
- vhy
- e1c
- w22qt4vhye1c3
- id
- vhz
- erc
- w22qt4vhzerct
- id
- z99
- qt4
- vdf
- z99qt4vdf4vc
- id
Then, as in your question, when you need to get all geohashes that start with w22qt4 you would do a query against:
firebaseRef.child('/geohash/w22/qt4/')
Which would then give you the vhy and vhz children which then have all the actual geohashes that you were interested in.
You can use a normal startAt query to find keys near the specified key. For example, in this case you'd:
var query = firebaseRef.child("geohash").startAt(null, 'c').limit(5);
query.on("child_added", ...);
This will give you the 5 elements after geoHashLatLng when sorted lexigraphically.
If you want to end your query at some specified key, you can do that as well. For example:
var query = firebaseRef.child("geohash").startAt(null, 'c').endAt('d');
I am looking for a general solution to a problem with couchdb views.
For example, have a view result like this:
{"total_rows":4,"offset":0,"rows":[
{"id":"1","key":["imported","1"],"value":null},
{"id":"2","key":["imported","2"],"value":null},
{"id":"3","key":["imported","3"],"value":null},
{"id":"4","key":["mapped","4"],"value":null},
{"id":"5,"key":["mapped","5"],"value":null}
]
1) If I want to select only "imported" documents I would use this:
view?startkey=["imported"]&endkey=["imported",{}]
2) If I want to select all imported documents with an higher id then 2:
view?startkey=["imported",2]&endkey=["imported",{}]
3) If I want to select all imported documents with an id between 2 and 4:
view?startkey=["imported",2]&endkey=["imported",4]
My Questtion is: How can I select all Rows with an id between 2 and 4?
You can try to extend the solution above, but prepend keys with a kind of "emit index" flag like this:
map: function (doc) {
emit ([0, doc.number, doc.category]); // direct order
emit ([1, doc.category, doc.number]); // reverse order
}
so you will be able to request them with
view?startkey=[0, 2]&endkey=[0, 4, {}]
or
view?startkey=[1, 'imported', 2]&endkey=[1, 'imported', 4]
But 2 different views will be better anyway.
I ran into the same problem a little while ago so I'll explain my solution. Inside of any map function you can have multiple emit() calls. A map function in your case might look like:
function(doc) {
emit([doc.number, doc.category], null);
emit([doc.category, doc.number], null);
}
You can also use ?include_docs=true to get the documents back from any of your queries. Then your query to get back rows 2 to 4 would be
view?startkey=[2]&endkey=[4,{}]
You can view the rules for sorting at CouchDB View Collation