Объединение входных данных из блестящих виджетов и запросов MySQL с меньшим количеством кода

#mysql #r #shiny

#mysql #r #блестящий

Вопрос:

У меня есть приложение, которое позволяет пользователям запрашивать базу данных MySQL, используя входные виджеты в блестящем приложении. Запросы также включают объединение таблиц. Код становится слишком длинным при использовании IF …Инструкции ELSE для определения, является ли виджет пустым или содержит какой-либо пользовательский ввод, как в коде ниже.

Пример данных MySQL может быть создан следующим образом:

    CREATE TABLE  quoteauthors (
     FirstName VARCHAR(255) ,
     LastName VARCHAR(255) ,
      authorID VARCHAR(255) 
    );

 CREATE TABLE  quotes (
   quote VARCHAR(255) ,    
    authorID VARCHAR(255) 
    );

 INSERT INTO quoteauthors
    VALUES ('Albert', 'Einstein', 'a1'),
           ('Stephen', 'Hawking', 'a2'),
           ('Isaac', 'Newton', 'a3');

  INSERT INTO quotes
     VALUES ('Unthinking respect for authority is the greatest enemy of truth.', 'a1'),
        ('In the middle of difficulty lies opportunity.', 'a1'),
        ('Intelligence is the ability to adapt to change.', 'a2'),
        ('Science is not only a disciple of reason but, also, one of romance and passion.', 'a2'),
        ('If I have seen further it is by standing on the shoulders of Giants.', 'a3'),
        ('I can calculate the motion of heavenly bodies but not the madness of people', 'a3');
  

Пример блестящего приложения, как показано ниже:

 library(shiny)
library(shinydashboard)
library(DBI)
library(RMySQL)

ui <- dashboardPage(
  dashboardHeader(),
  dashboardSidebar(
    sidebarMenu(
      menuItem("QUOTE Search", tabName = "Tabs", icon = icon("object-ungroup"))

    )
  ),
  dashboardBody(
    tabItem(tabName = "Tabs",
            fluidRow(
              column(width=3, 
                     box(
                       title="Search ",
                       solidHeader=TRUE,
                       collapsible=TRUE,
                       width=NULL,
                       textInput("quoteSearch1", " Search Term 1 ",  '', placeholder = "Type search term"),
                       radioButtons("combi", "Logical Operator to Combine  Terms:",
                                    c(
                                      "AND" = "AND",
                                      "OR" = "OR" 

                                    ), inline = TRUE),
                       textInput("quoteSearch2", " Search Term 2 ",  '', placeholder = "Type search term"),

                       selectInput("authorchoice", "Select AUTHOR", selected = NULL, multiple = T,
                                   choices=c('Albert','Stephen','Isaac')),
                       submitButton("Search")
                     )
              ),

              column( width=9,
                      tabBox(
                        width="100%",
                        tabPanel("Search Results", 
                                 htmlOutput("quotesearchdetails")
                        )))))))

server <- function(input, output) {


  output$quotesearchdetails <-renderUI({

    if(input$quoteSearch1!=""){
      con <- dbConnect(MySQL(), 
                       user='XXXXXXXXXXX', 
                       port = 3306, password='XXXXXXXXXXX', 
                       dbname='XXXXXXXXXXX', 
                       host='XXXXXXXXXXX')
                      dbSendQuery(con, "SET NAMES utf8mb4;")
                      dbSendQuery(con, "SET CHARACTER SET utf8mb4;")
                      dbSendQuery(con, "SET character_set_connection=utf8mb4;")
                      on.exit(dbDisconnect(con), add = TRUE) 

      quotedetails <- reactive({

        if (input$authorchoice == ""){
          if (input$quoteSearch2 == ""){
              dbGetQuery(con, statement = 
                       paste0(" SELECT q.quote, a.FirstName, a.LastName 
                                  FROM quotes q
                                   JOIN quoteauthors  a
                                     ON (q.authorID = a.authorID)
                                       WHERE (q.quote LIKE '%",input$quoteSearch1,"%')  "))                    

        }else{
          if (input$combi == "AND"){
            dbGetQuery(con, statement = 
                        paste0("
                               SELECT q.quote, a.FirstName, a.LastName 
                                FROM quotes q
                                 JOIN quoteauthors  a
                                   ON (q.authorID = a.authorID)
                                     WHERE (q.quote LIKE '%",input$quoteSearch1,"%' AND
q.quote LIKE '%",input$quoteSearch2,"%')"))


          }else{
            dbGetQuery(con, statement = 
                         paste0("
                                SELECT q.quote, a.FirstName, a.LastName 
                                 FROM quotes q
                                  JOIN quoteauthors  a
                                   ON (q.authorID = a.authorID)
                                    WHERE (q.quote LIKE '%",input$quoteSearch1,"%' 
                                 OR q.quote LIKE '%",input$quoteSearch2,"%')"))

          }                               

        }

        }else{
          if (input$quoteSearch2 == ""){
            dbGetQuery(con, statement = 
                         paste0("
                                SELECT q.quote, a.FirstName, a.LastName 
                                 FROM quotes q
                                  JOIN quoteauthors  a
                                   ON (q.authorID = a.authorID)
                                     WHERE (q.quote LIKE 
                                       '%",input$quoteSearch1,"%' 
                                       AND a.FirstName LIKE '%",input$authorchoice,"%') "))                                

          }else {
            if (input$combi == "AND"){
              dbGetQuery(con, statement = 
                           paste0("
                                  SELECT q.quote, a.FirstName, a.LastName 
                                   FROM quotes q
                                    JOIN quoteauthors  a
                                     ON (q.authorID = a.authorID)
                                      WHERE (q.quote LIKE '%",input$quoteSearch1,"%' AND
                                  q.quote LIKE '%",input$quoteSearch2,"%') AND
                                  a.FirstName LIKE '%",input$authorchoice,"%' "))

            }else{
              dbGetQuery(con, statement = 
                           paste0("
                                  SELECT q.quote, a.FirstName, a.LastName 
                                    FROM quotes q
                                     JOIN quoteauthors  a
                                       ON (q.authorID = a.authorID)
                                         WHERE (q.quote LIKE '%",input$quoteSearch1,"%' OR
                                  q.quote LIKE '%",input$quoteSearch2,"%')
                                  AND
                                  a.FirstName LIKE '%",input$authorchoice,"%' "))

            }
          }
      }

      })

      outputed=""
      quotedetailsreturned <- quotedetails()
      if (dim(quotedetailsreturned)[1] > 0){
        for(i in seq(from=1,to=dim(quotedetailsreturned)[1])){ 

          outputed<-paste(outputed,
                          paste("Author's First name: ",quotedetailsreturned[i,"FirstName"]),
                          sep="<br/><br/>")
          outputed<-paste(outputed,
                          paste("Author's Last name: ",quotedetailsreturned[i,"LastName"]),
                          sep="<br/><br/>")
          outputed<-paste(outputed,
                          paste("Quote: ",quotedetailsreturned[i,"quote"]),
                          sep="<br/><br/>")

        }

      } else { outputed <-"your search yielded no results."}

      HTML(outputed)
    }else {
      paste("Please input a search term at least in the first field")
    }


  })


}
shinyApp(ui, server)


  

Я ищу решение о том, как избежать повторения и длинных кодов с использованием IF…Инструкции ELSE в моем коде. Какие лучшие методы программирования я мог бы использовать для объединения запросов MySQL с пользовательским вводом в различных блестящих виджетах, включая TextInput, RadioButtons, selectize / selectInput и так далее, Учитывая, что некоторые входные данные могут быть оставлены пустыми, поэтому их не следует учитывать в запросе.

Ответ №1:

Я бы сначала построил только строку запроса, шаг за шагом, добавляя каждое предложение в соответствии с выбранными настройками. После того, как он был собран, выполните запрос. Делает код намного короче и проще для чтения.

Комментарии:

1. не могли бы вы быть достаточно любезны и показать нам демонстрационный фрагмент кода?