I know that i can get all databases with
GET _all_dbs
and also the last change of a database by
GET /{db}/_changes?descending=true&limit=1
the result will be like:
{
"results":[
{
"seq":112,
"id":"20e3480f5db4802d94a8193ac2246ae7",
"changes":[
{
"rev":"2-fb8204608047ce016282acbf3239cd01"
}
],
"deleted":true
}
],
"last_seq":112
}
Now is it possible to combine these statements to get something like:
{
"results":[
{
"db1":"1-fb8204608047ce016282acbf3239cd01"
},
{
"db2":"2-fb8204608047ce016282acbf3239cd02"
},
{
"db3":"2-fb8204608047ce016282acbf3239cd03"
},
{
"db4":"2-fb8204608047ce016282acbf3239cd04"
}
]
}
where "db1" is a database name and "2-fb8204608047ce016282acbf3239cd04" is the last _rev of the database.
There is no mechanism to make any query across multiple database in couchdb.
You can however do this from your application by joining the result of multiple queries.
Related
I am currently working on a laravel application where users can add content like articles and those article are searchable via a search engine. I would like to implement a modern full text search solution.
But the fact is it is possible for a user to put an article as private making it readable only by his followers or friends.
Implementing in simple SQL would be simple using a simple where clause on a pivot table relationship, but this is all but performant on large databases.
I made research's and devs on elastic search and other search engines but the limitation is that all the dataset is searchable and I cannot customize the filters according to a user defined relationship.
Should I create one index per user instead of having a global index ? This seems to have a huge impact also
I would really appreciate any of your thought about this, thanks in advance.
Try changing the perspective when looking at the problem.
Instead of thinking in terms of an article being accessible by certain groups of users, think in terms of a user and what articles she/he can access.
The search is always performed by a specific user, so it's known whom she/he follows (followed_user_ids) and is friends with (friend_ids). This information can be used at query build time.
The example query could look like this:
{
"query": {
"bool": {
"should": [
{
"term": {
"private": false
}
},
{
"bool": {
"filter": [
{
"term": {
"private": true
}
}
],
"should": [
{
"terms": {
"author_id": followed_user_ids,
}
},
{
"terms": {
"author_id": friend_ids,
}
}
],
"minimum_should_match": 1
}
}
]
}
}
}
It would find articles that:
are not private (visible to all); or
are private, but authored by friends or users followed by the current user
you can do this in Elasticsearch a few ways, that I can think of
ideally use document level security as it's the most secure approach, but don't use filtered aliases with this
add a boolean private field that you can then filter on. this is far less secure than DLS from above
if you've tried that second approach, then sharing what you did and what didn't work would help
I am new to Mongodb and I have to move my SQL Queries to mongodb now. I read the document and gained enough knowledge on writing mongodb QUeries but coming from MYSQL it will take time to get expertise on framing Mongo Queries.
I am trying to convert this query to Mongo for now using $Lookup
select * from orig_tbl emas
inner join cust-tbl_after_cleanup tmclient
on emas.state = tmclient.province
and emas.cons_city = tmclient.city
where
emas.state = 'VT' and
emas.can_match_address like concat('%',tmclient.street,'%')
and emas.can_cmp_name like concat('%',tmclient.name,'%')
and emas.can_match_address like concat('%',tmclient.house_num,'%')
and emas.can_match_address like concat('%',tmclient.postal_code,'%')
and emas.cons_city like concat('%',tmclient.city,'%')
and emas.State like concat('%',tmclient.province,'%')
group by tmclient.id,tmclient.name
As you can see I'm doing an inner join on multiple conditions and then doing a partial string match on number of cloumns. From the document I got to know how to do a multiple condition join but not sure how to do partial string match
Code so far:
aggregate(
[
{
'$match' : { 'name' : 'Walmart' }
},
{
'$lookup':
{
'from': 'entity_map_all_states',
'let': { 'order_city': "$city", 'order_qty': "$province" },
'pipeline': [
{ '$match':
{ '$expr':
{ '$and':
[
{ '$eq': [ "$cons_city", "$$order_city" ] },
{ '$eq': [ "$State", "$$order_qty" ] }
]
}
}
}
],
'as': "stockdata"
}
}
] )
Situation
In a project I have this code to select data from a table. Please note, it is working, I only don't get the result I expect.
serviceSurveyQuestions.find({
query: {
survey_id: this.survey_id,
user_id: this.$store.state.auth.user.id, //TODO move this to the hook!!
//todo make satus also not equal new
$or: [
{ status_id: process.env.mfp.statusSurveyQuestionStarted },
{ status_id: process.env.mfp.statusSurveyQuestionPlanned }
],
$sort: {
survey_question_question: 1
},
$limit: 150,
$select: [
'survey_question_question',
'survey_question_at',
'survey_question_answer',
'survey_question_details',
'survey_question_source_id',
'survey_question_source_answer_id',
'survey_question_source_user_id',
'survey_question_step',
'survey_question_dep_step',
'id'
]
}
}).then(page => {
this.listSurveyQuestions = page;
});
When I see what would be in one item of listSurveyQuestion I will see this:
{
"survey_question_question": "PEN 10 Scope vaststellen",
"survey_question_at": "2017-06-23T06:46:10.038Z",
"survey_question_answer": "",
"survey_question_details": "tester done",
"survey_question_source_id": 83499707,
"survey_question_source_answer_id": 74864,
"survey_question_source_user_id": 83488216,
"survey_question_step": 10,
"survey_question_dep_step": null,
"id": 4651,
"source_user": {
"user_id": 1005
},
"status": {
"status": "Planned"
},
"language": {
"language": "Dutch"
,
"source": {
"source": "MexonInControl - Pob - Dev (local)"
},
"survey_question": [{
"answer_type_id": 1014,
"answer_en": null,
"answer_nl": null,
"answer_explanation_en": null,
"answer_explanation_nl": null,
"survey_question_next_id": 4652
} ]
}
I know the result is comming from the configuration in my get and find hook of the service being called.
Expected Result
What I expect to happen is that the data returned is only the columns defined in the $SELECT. If I leave this as is, it will work but I'm getting to much data from the database which can be seen later as a security breach. Not with this example, but with other tables it will.
** Question **
So what do I need to change to have this functioning as expected. You could adapt the return of the service, but then I can't use the same service in other situations for the columns aren't available. Or can you pass an option to the service which will result in if (parameter = view 1) then return view 1 and so on.
** Solving **
Remark 1:
So I just see the 'cause' is a bit different. The configured hooks returns more columns from the question table which are not shown. So my guess here is that if you don't configure the includes in the find query, it will pass all includes. I need to check that and if this is the case, see if there is a option to not select the 'includes' as well.
Assuming that the hook you are referring to is setting hook.params.sequelize similar to this answer you will have to check if you included properties are also set in the $select query with something like this:
// GET /my-service?include=1
function (hook) {
const include = [];
const select = hook.params.query.$select;
// Go through all properties that are added via includes
['includeProp1', 'includeProp2'].forEach(propertyName => {
// If no $select or the include property is part of the $select
if(!select || select.indexOf(propertyName) !== -1) {
include.push({ model: ModelForIncludeProp1 });
}
});
hook.params.sequelize = { include };
return Promise.resolve(hook);
}
how can I write this mysql query in elasticsearch ?
SELECT *,count(products.store_id)
FROM stores
INNER JOIN products
ON stores.store_id=products.store_id
group by stores.store_id;
Elasticsearch is not exactly a database, it's a search engine and hence it supports very limited JOIN operations (parent-child queries).
If you want to execute the above query then you will have to rework the schema and try to have the data in one index (doesn't matter even if it's not in 2NF/3NF). Maybe you can index store_id along with each product document.
Now, coming back to the query, if you want to execure the above query on let's say one index then you can do it using TERMS aggregation. It will give you count of products grouped by store id, the request would look like this:
$ curl -XPOST 'http://localhost:9200/products/_search?search_type=count' -d '{
"query" : {
"filtered" : {
"filter" : {
"bool" : {
"must" : [
{ "term" : {"product_type" : "sometype"}}
]
}
}
}
},
"aggs" : {
"products" : {
"terms" : {
"field" : "store_id"
}
}
}
}'
I am having couchbase report documents stored in below format:
{
"agree_allowed":true,
"assigned_by":"",
"assigned_to":"",
"closed":[
],
"comments_allowed":true,
"details":"Test",
"email":"",
"status":"In Progress",
"subscribed":{
"user_cfd29b81f0263a380507":true,
"user_cfd29b81f0263a380508":true,
"user_cfd29b81f0263a380509":true,
"user_cfd29b81f0263a3805010":true
},
"summary":"Test",
"time_open":0,
"timestamp":"2015-07-17T15:34:30.864Z",
"type":"report",
"user_id":"user_cfd29b81f0263a380507",
"username":"test17"
}
json contain subscribed filed, it is list of user_id who follow reports.
Problem is i have to emit report document if subscribed field contain user_id, if i pass user_id ='user_cfd29b81f0263a380507' pass as key parameter. i am wondering how can use user_id to compare in view
here is the code i write:-
function map(doc, meta) {
if (doc.type == 'report' && doc.subscribed) {
for (var user_id in doc.subscribed) {
emit(doc.user_id, doc);
}
}
}
but it didn't return expected result.
Can anybody help.
If I understand your question I think you want the ability to query the users who have subscribed.
If that is the case the view code is wrong it is submitting doc.user_id and not user_id, which is the variable you assign values to in the loop but never use. In any case I think it would be better to use a different names to avoid confusion.
function map(doc, meta) {
if (doc.type == 'report' && doc.subscribed) {
for (var subscriber in doc.subscribed) {
emit(subscriber);
}
}
}
To query the users who have subscribed you would use key=user_cfd29b81f0263a380507. The result would be:
{
"total_rows": 4,
"rows": [
{
"id": "docs",
"key": "user_cfd29b81f0263a380507",
"value": null
}
]
}