2

From previous work on CouchDB 1.6.1, I know that it's possible to implement document joins in a couple ways:

For example, with a simple schema of 'studentsand 'courses:

// Students table
| Student ID | Student Name
| XYZ1       | Zach

// Courses table
| Course ID  | Student ID
| COURSE1    | XYZ1

This SQL query:

SELECT [Student Name], [Course ID] FROM Students RIGHT OUTER JOIN Courses ON Students.[Student ID] = Courses.[Student ID]

Could be implemented in CouchDB 1.6 with a map function:

// Map function
function(doc){
    if (doc.type == 'Course') emit(doc["Student ID"], doc);
    if (doc.type == 'Student') emit(doc["Student ID"], doc)
}

And either a group and reduce function

// Group would produce:
Student ID: [{course doc}, {student doc}, {course doc}, etc]

// Reduce would allow you to then process student and course docs for a single ID (with CouchDB protesting about expanding view indexes)

Or you could use a List function to iterate through either a grouped or ungrouped Map index.

Looking at documentation for Mango here, there is mention that _find (which I'm assuming is the 'Mango endpoint') uses indexes. I don't see way of saying 'where a field is equal to another field', but then I'm not very familiar with Mango at all...

Question:

  1. Can you 'emulate' document joins in Mango?
  2. If you can, would this be better or worse than using MapReduce to do the same thing?
Kerem
  • 11,377
  • 5
  • 59
  • 58
Zach Smith
  • 8,458
  • 13
  • 59
  • 133

1 Answers1

1

I think you already figured it out, but jut for the records : you can use equality selectors, and put them in a OR operator.

The query should be something looking like that :

{"studentId": "SOMEID" }
{"$or": [{"type": {"$eq": "Student"}}, {"type": {"$eq": "Course"}}]}

That being said, you seem to try to work with raw relational data in CouchBb. As I always say, you can't just dump relational data in CouchDb and expect to have a happy life. You may want to consider turning your relational data into rich domain objects before storing it in CouchDb.

tobiak777
  • 3,175
  • 1
  • 32
  • 44
  • In this case my relational data has inconsistent schemas. For example, if I have an entity called `Books`, with data coming from 10 different bookshops. so each bookshop has rows that are books, but columns have different names. My intent is to scrape all the 'books' into Couch, and then create a view that 'flattens' all the rows of books into a single entity. What is your opinion on this? – Zach Smith Apr 24 '17 at 14:06
  • So if I understand correctly, the `Books` entity is not flat initially, it is a "normal" nested structure. How do you intend to query the data ? will you know the types of the books you will be retrieving at query time ? (Basically I'd need to know what you are trying to achieve since there's more than one way to do it) – tobiak777 Apr 24 '17 at 17:48
  • I'm realizing this may not be directly related to your original question, would you mind creating another question and linking it from here so we have more space and context to discuss it – tobiak777 Apr 24 '17 at 17:49
  • sure. Here is it: https://stackoverflow.com/questions/43597244/is-it-advisable-to-use-mapreduce-to-flatten-irregular-entities-in-couchdb – Zach Smith Apr 24 '17 at 20:35